都2022年了,DOM事件应该要理解......

118 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

文章目的

1、理解事件流 2、使用事件处理程序 3、掌握不同的事件类型

一、事件流

事件流描述的是从页面中接受事件的顺序。 IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流

1、事件冒泡流

事件冒泡,即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上转播至最不具体的节点(文档document对象)。

<html>
<head>
   <title>事件流</title>
   <meta charset="utf-8">
<body>
   <div id="box">
       <input type="button" value="按钮1" id="btn1">
   </div>
</body>
</head>

比如上面的代码,当使用事件冒泡点击按钮1时,子级元素先触发,,父级元素后触发,即浏览器会认为你也逐级向上点击了id为box的div容器→点击了body→点击了html→点击了整个document文档对象

2、事件捕获

事件捕获的思想是不太具体的节点(文档document对象) 应该更早接收到事件,而最具体的节点最后接收到事件。

<html>
<head>
   <title>事件流</title>
   <meta charset="utf-8">
<body>
   <div id="box">
       <input type="button" value="按钮2" id="btn2">
   </div>
</body>
</head>

比如上面的代码,当使用事件捕获点击按钮1时,父级元素先触发,子级元素后触发,即浏览器会认为你率先点击了document文档对象→再点击html→点击了body→点击id为box的div容器→最后点击了按钮2

二、事件处理程序

1、HTML事件处理程序

HTML事件处理程序的HTML和JS的代码耦合度太高,当修改一处代码时都需要进行修改

<html>
<head>
   <title>事件流</title>
   <meta charset="utf-8">
<body>
   <div id="box">
      <input type="button" value="按钮" id="btn" onclick="showMes()">
   </div>
   <script>
      function showMes() {
         alert("Hello")
      }
   </script>
</body>
</head>

2、DOM0级事件处理程序

DOM0级事件处理程序是比较传统、简单且用得比较多,具有跨浏览器优势的方式,指把一个函数赋值给一个事件的处理程序属性

<html>
<head>
   <title>事件流</title>
   <meta charset="utf-8">
<body>
   <div id="box">
      <input type="button" value="按钮2" id="btn2">
   </div>
   <script>
      var btn2 = document.getElementById("btn2");
      btn.onclick = function () {
         alert("DOM0级事件处理程序触发")
      }
   </script>
</body>
</head>

DOM0级事件处理程序通过document.getElementById("ID名")获取HTML的元素,不直接在HTML代码写入,而是在script里单独写入

DOM0级事件处理程序不存在HTML和JS代码耦合度太高的问题

3、DOM2级事件处理程序

没有DOM1级事件处理程序。

DOM2级事件定义了两个方法,用于处理指定和删除事件处理程序的操作:

  • addEventListener()
  • removeEventListener()。

它们都接收三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。

<html><head>
   <title>事件流</title>
   <meta charset="utf-8"><body>
   <div id="box">
      <input type="button" value="按钮" id="btn" onclick="showMes()">
      <input type="button" value="按钮3" id="btn3">
   </div>
   <script>
      function showMes() {
         alert("DOM2级事件处理程序触发")
      }
      var btn3 = document.getElementById("btn3")
      btn3.addEventListener('mouseover', showMes, false)//false兼容各种浏览器
      btn3.addEventListener('click', function () {
         alert(this.value)
      }, false)
   </script>
</body>
</head>

通过addEventListener()添加的多个事件,只能通过removeEventListener()删除事件

// 删除事件
btn3.removeEventListener('mouseover', showMes, false)

DOM2级事件处理程序方法不适合用在IE浏览器中,IE有自己的事件处理程序方法

4、IE事件处理程序

attachEvent()添加事件 detachEvent()删除事件 这两个方法接收相同的两个参数:事件处理程序名称与事件处理函数

<html><head>
   <title>事件流</title>
   <meta charset="utf-8"><body>
   <div id="box">
      <input type="button" value="按钮" id="btn" onclick="showMes()">
      <input type="button" value="按钮3" id="btn3">
   </div>
   <script>
      function showMes() {
         alert("DOM2级事件处理程序触发")
      }
      var btn3 = document.getElementById("btn3")
      btn3.attachEvent('onclick', showMes)//IE添加事件
      btn3.detachEvent('onclick', showMes)//IE删除事件
   </script>
</body>
</head>

IE只使用在IE浏览器,适用性太小,因此跨浏览的事件处理程序很有必要

5、跨浏览器的事件处理程序

分情况处理跨浏览器的事件处理程序

function showMes() {
  alert("DOM2级事件处理程序触发")
}
var eventUtil = {
  // 添加句柄:function (element, type, handler){},需要触发的元素,触发事件的类型,触发了什么样的具体操作
  addHandler: function (element, type, handler) {
    if (element.addEventListener) {
      // DOM2级
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent) {
      // IE
      element.attachEvent('on' + type, handler);
    } else {
      // DOM0级,等价于element.onclick = handler
      element['on' + type] = handler;
    }
  },
  // 删除句柄
  removeHandler: function (element, type, handler) {
    if (element.removeEventListener) {
      element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) {
      element.detachEvent('on' + type, handler);
    } else {
      element['on' + type] = null;
    }
  },
}
// 具体调用
eventUtil.addHandler(btn3, 'click', showMes)

三、事件对象

事件对象event是什么? 事件对象提供有关事件的详细信息,因而可以在事件处理程序中通过事件对象获取有关事件的相关信息,例如获取事件源的名称、键盘按键的状态、鼠标光标的位置、鼠标按钮的状态等信息。

事件对象用于描述所产生的事件。调用事件处理程序时,JS会把事件对象作为参数传给事件处理程序。

<html>
<head>
   <title>事件流</title>
   <meta charset="utf-8">
<body>
   <div id="box">
      <input type="button" value="按钮" id="btn" onclick="showMes()">
   </div>
   <script>
      function showMes(event) {
         alert(event.type)//获取event.type事件类型
      }
   </script>
</body>
</head>

1、DOM中的事件对象

  • (1)、type:获取事件类型
  • (2)、target:事件目标
  • (3)、stopPropagation() 阻止事件冒泡
  • (4)、preventDefault() 阻止事件的默认行为。如a标签默认的行为href跳转属性
function showMes(event) {
    alert(event.type.nodeName);
    console.log(event.target)
    event.stopPropagation();
    event.preventDefault();
}

常用DOM事件对象

属性/方法说明
type获取事件类型
target(nodeName)在 W3C 标准浏览器中获取事件源
clientX用于获取鼠标事件发生时相对于可视窗口左上角的鼠标光标的水平坐标
clientY用于获取鼠标事件发生时相对于可视窗口左上角的鼠标光标的垂直坐标
ctrlKey用于判断键盘事件发生时“Ctrl”键是否被按下
keyCode返回被按下的键盘按键对应的键码值
relatedTarget用于获取鼠标事件发生时与事件源相关的节点
screenX用于获取鼠标事件发生时相对于文档窗口的鼠标光标的水平坐标
screenY用于获取鼠标事件发生时相对于文档窗口的鼠标光标的垂直坐标
shiftKey用于判断键盘事件发生时“Shift”键是否被按下
offsetX用于获取鼠标事件发生时相对于事件源的左上角的水平偏移,在 Chrome. Opera 和 Safari 浏览器中,左 上角为外边框的位置;在 Firefox 和 IE 浏览器中,左上角为内边框的位置
offsetY用于获取鼠标事件发生时相对于事件源的左上角的垂直偏移,浏览器的情况与 offsetX 同
srcElement用于在 IE8 及以下版本的IE浏览器中,获取事件源
altKey用于判断键盘事件发生时“Alt”键是否被按下
button用于判断鼠标事件发生时哪个鼠标键被点击了。在遵循 W3C 标准的浏览器中,鼠标左、中、右键分別用 0、1 和 2 表示;不遵循 W3C 标准的IE浏览器中,鼠标左、中、右键分别用 1、4 和 2 表示
returnValue取值为 true 或 falseo 用于在 IE8 及以下版本的IE浏览器中决定是否不执行与事件关联的默认动作。当值为 false 时,不执行默认动作

具体DOM事件对象

www.runoob.com/jsref/dom-o…

2、IE中的事件对象

  • (1)、type:获取事件类型
  • (2)、srcElement:事件目标
  • (3)、cancelBubble=true阻止事件冒泡
  • (4)、returnValue=false阻止事件的默认行为