1. 注册事件

给元素添加事件,称为注册事件或者绑定事件

  1. // 方法1:给DOM元素的属性赋值
  2. // 特点:同一个元素,同一个事件,只能设置一个处理函数
  3. // 最后注册的处理函数将会覆盖前面的处理函数
  4. <button>按钮</button>
  5. let btn = document.querySelector('button')
  6. btn.onclick = function() {
  7. console.log('我被点击了')
  8. }
//方法2:调用DOM的addEventListener()方法
// 特点:同一个元素,同一个事件可以注册多个监听器,按注册顺序依次执行

<button>按钮</button>
let btn = document.querySelector('button')
btn.addEventListener('click', function() {
    console.log('我被点击了')
})

2. 事件监听函数

  • target.addEventListener(type, listener, options)
    • type: 事件类型
    • listener: 事件处理方法
    • options: 传递一个对象,可选,默认全是false
      • capture: 是否捕获阶段监听
      • once: 是否只监听一次
      • passive: 是否忽略preventDefault
  • target.addEventListener(type, listener, useCapture)
    • useCapture: 可选,true表示在捕获阶段调用listener,false表示冒泡阶段
  • target.removeEventListener
    • target.removeEventListener(‘click’, handler)
    • target.removeEventListener(‘click’, handler, true) ```javascript function isClick() { console.log(‘我被点击了’) }

let btn = document.querySelector(‘button’) btn.addEventListener(‘click’, isClick)

btn.removeEventListener(‘click’, isClick) // 取消事件监听


**

<a name="RPgTA"></a>
#  3. DOM事件流

**HTML中的标签都是互相嵌套的,我们可以将元素想象成一个盒子装一个盒子,document是最外面的大盒子。当你单击一个div时,同时你也单击了div的父元素,甚至整个页面。那么是先执行父元素的单击事件,还是先执行div的单击事件?**<br />**

- 事件流描述的是从页面中接收事件的顺序
- 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流


**DOM 事件流会经历3个阶段:**

1. 捕获阶段
2. 当前目标阶段
3. 冒泡阶段

    我们向水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点( 具体元素)之后漂浮到水面上,这个过程相当于事件冒泡。<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/2205407/1611320102963-5a82b5ba-2cca-46d2-82fa-e47b1ecdb22c.png#align=left&display=inline&height=254&margin=%5Bobject%20Object%5D&name=image.png&originHeight=254&originWidth=689&size=29319&status=done&style=none&width=689)
```html
<div class="parent">parent
  <div class="child">child
    <div class="target">target</div>
  </div>
</div>
<style>
  div {
    border: 1px solid;
    margin: 10px;
  }
</style>
<script>
  const $ = s => document.querySelector(s)
  $('.parent').addEventListener('click', function () {
    console.log('在捕获阶段,parent 开始处理')
  }, true)
  $('.child').addEventListener('click', function () {
    console.log('在捕获阶段,child 开始处理')
    // e.stopPropagation()
  }, true)
  $('.target').addEventListener('click', function () {
    console.log('在捕获阶段,target 开始处理')
  }, true)
  $('.parent').addEventListener('click', function () {
    console.log('在冒泡阶段,parent 开始处理')
  }, false)
  $('.child').addEventListener('click', function (e) {
    console.log('在冒泡阶段,child 开始处理')
  }, false)
  $('.target').addEventListener('click', function (e) {
    console.log('在冒泡阶段,target 开始处理')
  }, false)
</script>

4. 事件对象**

事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象**。**
例如:

  1. 谁绑定了这个事件。
  2. 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。
  3. 键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。**

事件触发发生时就会产生事件对象,并且系统会以实参的形式传给事件处理函数。
所以,在事件处理函数中声明1个形参用来接收事件对象。

事件对象的属性和方法**

  • e.target 返回触发事件的对象
  • e.type 返回事件的类型(click,mouseover等)
  • e.preventDefault() 该方法阻止默认事件(不让链接跳转等)
  • e.stopPropagation() 阻止冒泡

**

e.target 和 this 的区别

  • this 是事件绑定的元素(绑定这个事件处理函数的元素)
  • e.target 是事件触发的元素
    <div>123</div>
    <script>
        var div = document.querySelector('div')
        div.addEventListener('click', function(e) {
            // e.target 和 this指向的都是div
            console.log(e.target)
            console.log(this)
        })
    </script>
    <ul>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
              // 我们给ul 绑定了事件  那么this 就指向ul  
              console.log(this)   // ul

              // e.target 触发了事件的对象 我们点击的是li e.target 指向的就是li
              console.log(e.target) // li
        })
    </script>

5. 阻止默认行为

html中一些标签有默认行为,例如a标签被单击后,默认会进行页面跳转
target.preventDefault()可以阻止默认行为

    <a href="https://www.baidu.com">百度</a>
    <script>
        // 阻止默认行为 让链接不跳转 
        var a = document.querySelector('a')
        a.addEventListener('click', function(e) {
             e.preventDefault()  
        })
    </script>

6. 阻止事件冒泡

target.stopPropagation()可以阻止事件冒泡

    <div class="father">father父亲
        <div class="son">son儿子</div>
    </div>
    <script>
        let son = document.querySelector('.son')
            // 给son注册单击事件
        son.addEventListener('click', function(e) {
            console.log('son')
            e.stopPropagation() // stop 停止  Propagation 传播
        }, false)

        let father = document.querySelector('.father')
            // 给father注册单击事件
        father.addEventListener('click', function() {
            console.log('father')
        }, false)

            // 给document注册单击事件
        document.addEventListener('click', function() {
            console.log('document')
        })
    </script>

7. 事件委托

事件委托:
不给子元素注册事件
给父元素注册事件
把处理代码在父元素的事件中执行

事件委托的原理:
给父元素注册事件
利用事件冒泡,当子元素的事件触发,会冒泡到父元素
然后去控制相应的子元素

事件委托的作用:
我们只操作了一次 DOM ,提高了程序的性能
动态新创建的子元素,也拥有事件

    <ul>
        <li>刘德华</li>
        <li>刘德华</li>
        <li>刘德华</li>
        <li>刘德华</li>
        <li>刘德华</li>
    </ul>
    <script>
        // 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
        var ul = document.querySelector('ul')
        ul.addEventListener('click', function(e) {
            // e.target 这个可以得到我们点击的对象
            e.target.style.backgroundColor = 'pink'
        })
    </script>

8. 鼠标事件

鼠标事件
image.png

案例:禁止选中文字和禁止右键菜单

<body>
    我是一段不愿意分享的文字
    <script>
        // 1. contextmenu 我们可以禁用右键菜单
        document.addEventListener('contextmenu', function(e) {
                e.preventDefault();
        })
        // 2. 禁止选中文字 selectstart
        document.addEventListener('selectstart', function(e) {
            e.preventDefault();
        })
    </script>
</body>


鼠标事件对象
image.png

案例:跟随鼠标的天使

    <style>
        img {
          position: absolute;
      }
    </style>
    <img src="images/angel.gif" alt="">
    <script>
        let pic = document.querySelector('img')
        document.addEventListener('mousemove', function(e) {
            // 1. mousemove只要我们鼠标移动1px 就会触发这个事件
            // 2.核心原理: 每次鼠标移动,我们都会获得最新的鼠标坐标, 
            // 把这个x和y坐标做为图片的top和left 值就可以移动图片
            let x = e.pageX
            let y = e.pageY
            console.log('x坐标是' + x, 'y坐标是' + y)
            //3 . 千万不要忘记给left 和top 添加px 单位
            pic.style.left = x + 'px'
            pic.style.top = y + 'px'
        })
    </script>

9. 键盘事件

键盘事件
image.png
注意:三个事件的执行顺序是keydown—-keypress—-keyup
**

键盘事件对象
image.png

案例:使用keyCode属性判断用户按下哪个键

    <script>
        // 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
        document.addEventListener('keyup', function(e) {
            console.log('up:' + e.keyCode)
            // 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
            if (e.keyCode === 65) {
                console.log('您按下的a键')
            } else {
                console.log('您没有按下a键')
            }
        })
        document.addEventListener('keypress', function(e) {
            // console.log(e)
            console.log('press:' + e.keyCode)
        })
    </script>

案例:模拟京东按键输入内容
需求:当我们按下 s 键, 光标就定位到搜索框(文本框获得焦点)

    <input type="text">
    <script>
        // 获取输入框
        let search = document.querySelector('input')
            // 给document注册keyup事件
        document.addEventListener('keyup', function(e) {
            // 判断keyCode的值
            if (e.keyCode === 83) {
                // 触发输入框的获得焦点事件
                search.focus()
            }
        })
    </script>