# 事件监听

执行下面的代码，监听元素的点击事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <button>Click</button>
    <script type="text/javascript">
        const btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            console.log('Hello World!');
        });
    </script>
</body>
</html>
```

还可以为同一个元素绑定多个相同类型的监听事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <button>Click</button>
    <script type="text/javascript">
        const btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            console.log('Hello World!');
        });
        btn.addEventListener('click', function() {
            console.log('Hello JavaScript!');
        });
    </script>
</body>
</html>
```

执行下面的代码，监听元素的鼠标移动事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
    <style type="text/css">
        .box {
            width: 500px;
            height: 500px;
            background-color: red;
        }
    </style>
</head>
<body>
    <div class="box">Hello World!</div>
    <script type="text/javascript">
        const box = document.querySelector('.box');
        box.addEventListener('mouseenter', function() {
            console.log('enter');
        });
        box.addEventListener('mouseleave', function() {
            console.log('leave');
        });
    </script>
</body>
</html>
```

执行下面的代码，监听表单的输入操作事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <form action="#" method="post">
        <input type="text" name="username">
    </form>
    <script type="text/javascript">
        const input = document.querySelector('input');
        input.addEventListener('keydown', function() {
            console.log('down');
        });
        input.addEventListener('keyup', function(e) {
            console.log('up');
            console.log(e.key);
        });
    </script>
</body>
</html>
```

事件冒泡是指当一个元素的事件被触发时，同样的事件将会在该元素的所有祖先元素中依次被触发。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <div class="box1">
        <div class="box2">
            <div class="box3">Hello World!</div>
        </div>
    </div>
    <script type="text/javascript">
        const box1 = document.querySelector('.box1');
        box1.addEventListener('click', function() {
            console.log('box1');
        });
        const box2 = document.querySelector('.box2');
        box2.addEventListener('click', function() {
            console.log('box2');
        });
        const box3 = document.querySelector('.box3');
        box3.addEventListener('click', function() {
            console.log('box3');
        });
    </script>
</body>
</html>
```

执行下面的代码，阻止冒泡事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <div class="box1">
        <div class="box2">
            <div class="box3">Hello World!</div>
        </div>
    </div>
    <script type="text/javascript">
        const box1 = document.querySelector('.box1');
        box1.addEventListener('click', function() {
            console.log('box1');
        });
        const box2 = document.querySelector('.box2');
        box2.addEventListener('click', function() {
            console.log('box2');
        });
        const box3 = document.querySelector('.box3');
        box3.addEventListener('click', function(e) {
            console.log('box3');
            e.stopPropagation();
        });
    </script>
</body>
</html>
```

执行下面的代码，利用事件冒泡实现事件委托。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <p>Hello World!</p>
    </ul>
    <script type="text/javascript">
        const ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            if (e.target.tagName === 'LI') {
                e.target.style.color = 'red';
            }
        });
    </script>
</body>
</html>
```

执行下面的代码，阻止元素的默认行为。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <form action="#" method="post">
        <input type="text" name="username">
    </form>
    <a href="#">Click</a>
    <script type="text/javascript">
        const form = document.querySelector('form');
        form.addEventListener('submit', function(e) {
            e.preventDefault();
        });
        const a = document.querySelector('a');
        a.addEventListener('click', function(e) {
            e.preventDefault();
        });
    </script>
</body>
</html>
```

执行下面的代码，监听页面加载事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <script type="text/javascript">
        window.addEventListener('load', function() {
            console.log('Hello JavaScript!');
        });
        document.addEventListener('DOMContentLoaded', function() {
            console.log('Hello World!');
        });
    </script>
</body>
</html>
```

执行下面的代码，监听页面滚动事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
    <style>
        .box {
            height: 5000px;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script type="text/javascript">
        window.addEventListener('scroll', function() {
            console.log('scroll');
        });
    </script>
</body>
</html>
```

执行下面的代码，监听窗口尺寸改变事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <script type="text/javascript">
        window.addEventListener('resize', function() {
            console.log('resize');
        });
    </script>
</body>
</html>
```

执行下面的代码，监听移动端事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <script type="text/javascript">
        document.addEventListener('touchstart', function() {
            console.log('touchstart');
        });
        document.addEventListener('touchmove', function() {
            console.log('touchmove');
        });
        document.addEventListener('touchend', function() {
            console.log('touchend');
        });
    </script>
</body>
</html>
```

执行下面的代码，解绑元素的监听事件。

```html
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
</head>
<body>
    <button>Click</button>
    <script type="text/javascript">
        function func() {
            console.log('Hello World!');
        }
        const btn = document.querySelector('button');
        btn.addEventListener('click', func);
        btn.removeEventListener('click', func);
    </script>
</body>
</html>
```

