3.事件总结

118 阅读8分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。看完事件的相关内容,写的一篇笔记。

事件

1.0 了解事件

我们使用代码的方式和一个内容约定好一个行为,触发该行为是会有相应的代码执行。

1.0.1 事件三要素

  1. 事件源:和谁约定事件*(和谁触发不一样)*。
  2. 事件类型:约定了一个什么事件。
  3. 事件处理函数:当行为发生时,需要执行的函数。

这三个内容的目的是为了绑定事件,注册事件,就是提前做好约定。

1.1 事件绑定/解绑

1.1.1 事件绑定

  1. DOM 0级事件

    事件源.on事件类型 = 事件处理函数

    一个事件源的同一个事件类型,只能绑定一个事件处理函数。

    div.onclick = ()=>{
        console.log('我被点击了');
    }
    
  2. DOM 2级事件(事件侦听器/事件监听器)

    DOM 2级事件由于解绑的需要,所以需要将事件处理函数单独书写出来。

    标准浏览器:事件源.addEventListener('事件类型',事件处理函数)

    可以给一个事件源的同一个事件类型绑定多个事件处理函数,按照绑定顺序,顺序执行。

    div.addEventListener('click',()=>{
                console.log('我被点击了');
            })
    

    IE低版本:事件源.attachEvent('on事件类型',事件处理函数)

    可以给一个事件源的同一个事件类型绑定多个事件处理函数,按照绑定顺序,倒序执行。

1.1.2 事件解绑

  1. DOM 0级事件

    事件源.on事件类型 = null

  2. DOM 2级事件

    标准浏览器:事件源.removeEventListener('事件类型',事件处理函数)

    IE低版本:事件源.deattachEvent('on事件类型',事件处理函数)

        <button id="but">解绑</button>
        <div id="div"></div>
        <script>
            function click(){
                console.log('shot');
            }
            div.addEventListener('click',click);
            but.onclick = ()=>{
                div.removeEventListener('click',click)
                console.log('over');
            }
        </script>
    

1.2 事件类型

js的原生事件没有大写字母

1.2.1 鼠标事件

依赖鼠标行为触发的时间。

  1. click 鼠标左键单击。
  2. dblclick 鼠标左键双击。
  3. contextmenu 鼠标右键单击。
  4. mousedown 鼠标按下(任何一个按键按下)。
  5. mouseup 鼠标抬起(任何一个按键按下后抬起)。
  6. mousemove 鼠标移动(光标只要位置改变就会触发,大概16ms一次)。
  7. mouseover/mouseout 鼠标移入/鼠标移出。移入子元素也会触发
  8. mouseenter/mouseleave 鼠标移入/鼠标移出。移入子元素不会触发

1.2.2 键盘事件

依赖键盘触发的事件。

所有元素都可以绑定键盘事件,但不是谁都能触发,一般可以有window/document/表单元素触发。

触发键盘事件一般不考虑中文输入法。

  1. keydown 键盘按键按下。
  2. keyup 键盘按键按下后抬起。
  3. keypress 键盘真实键入内容,或者回车键

1.2.3 浏览器事件

浏览器事件见 2.5 常见事件

1.2.4 表单事件

专门提供给表单的事件。

  1. focus 聚焦事件。
  2. blur 失焦事件。
  3. change 聚焦和失焦的时候内容不一样。
  4. input 只要表单元素输入或删除内容,就会触发。
  5. reset 重置,需要绑定给form标签才会触发。
  6. submit 提交,需要绑定给form标签才会触发。

1.2.5 触摸事件

移动端事件,只能在移动端设备使用(需要能够有触摸功能)

  1. touchstart 触摸开始,手触摸到屏幕的瞬间。
  2. touchmove 触摸移动,手在屏幕移动的时候。
  3. touchend 触摸结束,手在结束触摸屏幕的瞬间。

1.3 事件对象

记录本次事件触发的所有信息的对象数据类型。

1.3.1 获取事件对象

标准浏览器:

直接在事件处理函数书写一个形参,会在事件触发的时候,浏览器自动传递实参,即事件对象。

IE低版本:

直接使用window.event 来获取事件对象。

兼容:div.onclick = (event)=>{event = event || window.event;}

1.3.2 鼠标事件

  1. clientX / clientY

    光标相对于浏览器可视窗口左上角的坐标位置。

  2. pageX / pageY

    光标相对于文档流左上角的坐标位置。

  3. offsetX / offsetY

    光标相对于触发事件的元素左上角的坐标位置。

1.3.3 键盘事件

  1. keyCode

    按下的是哪一个按键。

  2. 组合按键

    shiftKey / ctrlKey / alyKey / metaKey 都是布尔类型。

1.4 事件传播

当一个事件在浏览器中触发的时候,不光是在自己元素身上触发,是会传播出去的。

1.4.1 概念

当在一个元素身上触发行为的时候,会按照结构父级的顺序,向上直到window传递该行为。

真实的传播

首先 window 接收到行为, 按照结构级别逐层向下传递到准确触发事件的元素

在从准确触发事件的元素向上传递, 回到 window

在这个过程中, 每一个内容都接受了两次行为, 但是为什么事件处理函数只被调用了一次

因为浏览器的事件执行机制

捕获阶段(window -> 目标) 目标阶段 冒泡阶段(目标 -> window)

1.4.2 捕获 目标 冒泡

事件捕获:事件传播过程中,从window到目标的过程。

事件目标:准确触发事件的那个元素。

事件冒泡:事件传播过程中,从目标到window的过程。

  1. 如何获取事件目标?

    在事件对象内有一个固定信息表示本次事件的事件目标

    兼容:var target = event.target || event.srcElement

  2. 事件执行顺序

    在IE低版本,只能按照冒泡的顺序执行。

    在标准浏览器,默认在冒泡阶段执行,可以选择在捕获阶段执行。

    DOM 0级事件无法修改,只能在DOM 2级事件中通过添加第三个参数执行。默认false,表示冒泡阶段执行,true表示捕获阶段执行。

1.4.3 阻止事件传播

标准浏览器:event.stopPropagation()

IE低版本:event.cancelBubble = true

兼容:try-catch,因为会报错,所有用try-catch

1.4.4 默认行为

不需要绑定事件,当触发行为就是出现效果的事情,叫做默认行为。

标准浏览器:event.preventDefault()

IE低版本:event.returnValue = false

兼容:try-catch

通用:在事件处理函数最后return false;,但是需要事件处理函数中不能出错。

1.4.5 事件委托

给多个元素绑定事件时,可将事件绑定给结构父级,当事件目标为自己时再执行。对于动态添加元素很友好。

原则:尽可能找到距离最近的公共的父级,尽可能找到在页面上不动的元素来委托

<body>
  <button>添加一个 li</button>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>

  <script>

    // 0. 获取 ul 标签
    // 因为 ul 是所有 li 共同的父级结构
    var ul = document.querySelector('ul')

    // 1. 给 ul 绑定点击事件
    ul.onclick = function (e) {
      // 处理事件对象兼容
      e = e || window.event
      // 处理事件目标兼容
      var target = e.target || e.srcElement

      // 2. 判断你点击的确实是 li
      if (target.nodeName === 'LI') {
        // 在控制台打印你点击的这个 li 的文本内容
        console.log(target.innerText)
      }
    }

    // 点击 button 按钮生成 li
    var btn = document.querySelector('button')

    btn.onclick = function () {
      var li = document.createElement('li')
      li.innerHTML = '我是新来的'

      ul.appendChild(li)
    }
  </script>
</body>

1.x 总结

1.x.1 名词解释:

  1. 事件源: 绑定在 谁 身上的事件。

  2. 事件类型: 绑定 什么 事件。

  3. 事件处理函数: 当行为发生的时候, 执行的函数。

  4. 事件侦听器: DOM 2级 绑定事件的方式

    标准浏览器: addEventListener()

    IE 低版本: attachEvent()

  5. 事件解绑: 取消已经绑定好的事件

    DOM 0级事件: 直接赋值为 null

    标准浏览器中 DOM2级事件: removeEventListener()

    IE 低版本中 DOM2级事件: deattchEvent()

    注意: DOM2级事件的解绑, 在绑定的时候, 要把函数单独书写出来, 以函数名的形式进行绑定

  6. 事件传播: 按照结构父级的顺序, 从元素到 window 传递事件的行为。

  7. 事件捕获: 按照从 window 到 目标 的顺序传递行为的过程。

  8. 事件冒泡: 按照从 目标 到 window 的顺序传递行为的过程。

  9. 事件目标: 当事件触发的时候, 那个准确触发事件的元素。

    标准浏览器: target

    IE 低版本: srcElement

  10. 阻止事件传播: 不让事件继续传播, 不会触发父级结构的事件函数了

    标准浏览器: stopPropagation()

    IE 低版本: cancelBubble = true

  11. 阻止默认行为: 不让元素默认的行为出现

    标准浏览器: preventDefault()

    IE 低版本: returnValue = false

  12. 事件委托: 把自己的事件委托给共同的结构父级

    在父级的事件内, 通过事件目标判断来决定执行什么内容

  13. 事件对象: 当事件触发的时候, 浏览器提供的一个对象数据类型

    里面记录着本次事件的所有相关信息

    标准浏览器: 形参的方式

    IE 低版本: window.event

1.x.2 兼容性

  1. DOM2级事件绑定

    标准浏览器: 事件源.addEventListener('事件类型', 事件处理函数)

    IE 低版本: 事件源.attachEvent('on事件类型', 事件处理函数)

  2. DOM2级事件解绑

    标准浏览器: 事件源.removeEventListener('事件类型', 事件处理函数)

    IE 低版本: 事件源.detachEvent('on事件类型', 事件处理函数)

  3. 事件对象的获取

    标准浏览器: 形参方式接受

    IE 低版本: window.event

  4. 事件对象中的键盘编码

    标准浏览器: 事件对象.keyCode

    FIreFox < 20: 事件对象.which

  5. 事件目标的兼容:

    标准浏览器: 事件对象.target

    IE 低版本: 事件对象.srcElement

  6. 阻止事件传播:

    标准浏览器: 事件对象.stopPropagation()

    IE 低版本: 事件对象.cancelBubble = true

  7. 阻止默认行为:

    标准浏览器: 事件对象.preventDefault()

    IE 低版本: 事件对象.returnValue = false