addEventListener()方法和 on 的区别

addEventListener()方法相比on事件类型,有什么区别吗?为什么要使用 addEventListener?什么是事件冒泡?

说明:on不是指jQuery里的on()方法,是原生的“on+事件类型”,即诸如:onclick、onmouseover等;本文着重介绍的是addEventListener;

addEventListener()on的区别要从事件侦听(Event Listeners)和内联事件(Inline Events)说起,直接看下面的demo代码。

事件侦听(Event Listeners)

EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 

事件目标可以是一个文档上的元素 Document 本身,或者任何其他支持事件的对象 (比如 XMLHttpRequest)。

addEventListener语法

element.addEventListener(event, function, useCapture)
参数 event:表示监听事件类型的字符串(必须);
参数 function:一个实现了 EventListener 接口的对象,或者是一个函数(必须);
参数 useCapture:布尔值,指定事件是否在捕获或冒泡阶段执行(可选);
useCapture可能值(事件冒泡,稍后介绍):
true - 事件句柄在捕获阶段执行;
false- 默认。事件句柄在冒泡阶段执行;
 
示例代码:
  1. window.onload = function(){ 
  2.     var box = document.getElementById("box"); 
  3.     box.addEventListener("click",function(){ 
  4.         console.log("我是box1"); 
  5.     }) 
  6.     box.addEventListener("click",function(){ 
  7.         console.log("我是box2"); 
  8.     }) 
  9. //运行结果: 
  10. //我是box1 
  11. //我是box2 

addEventListener特点

addEventListener 是 W3C DOM 规范中提供的注册事件监听器的方法。它的优点包括:

  • 允许给一个事件注册多个 listener。当存在其他的库时,使用 DHTML 库或者 Mozilla extensions 不会出现问题。
  • 提供了一种更精细的手段控制 listener 的触发阶段。(即可以选择捕获或者冒泡)。
  • 对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。

内联事件(Inline Events)

由于内联事件是作为元素属性保存起来的,这些属性可以被覆盖,所以如果为同一个事件绑定了多个处理程序,那么最后一个处理程序会覆盖之前的程序。

  1. window.onload = function(){ 
  2.     var box = document.getElementById("box"); 
  3.     box.onclick = function(){ 
  4.         console.log("我是box1"); 
  5.     } 
  6.     box.onclick = function(){ 
  7.         box.style.fontSize = "18px"
  8.         console.log("我是box2"); 
  9.     } 
  10. //运行结果: 
  11. //我是box2  //覆盖了前者 

事件冒泡

点击div里a标签,触发了div的点击事件?这就是JS事件冒泡。JS事件冒泡分向上冒泡、向下冒泡;

好吧,有时候JS事件冒泡是我们想要的,有时候JS事件冒泡是讨厌的,Web前端开发者需根据项目实际情况处理。

向上冒泡

即:从子元素再到父元素冒泡,默认情况事件是按照事件冒泡的执行顺序进行的。

  1. box.addEventListener("click",function(){ 
  2.     console.log("box"); 
  3. }) 
  4. child.addEventListener("click",function(){ 
  5.     console.log("child"); 
  6. }) 
  7. //执行的结果: 
  8. //child 
  9. //box 

如何做到从父元素向子元素的顺序冒泡呢?下面有请 addEventListener 闪亮登场!

向下冒泡

 

  1. box.addEventListener("click",function(){ 
  2.     console.log("box"); 
  3. },true)//关键true 
  4. child.addEventListener("click",function(){ 
  5.     console.log("child"); 
  6. }) 
  7. //执行的结果: 
  8. //box 
  9. //child 

addEventListener()方法中的第三个参数true是向下冒泡的关键,它规定事件句柄在捕获阶段执行。

浏览器兼容性

兼容性一直是程序员须警惕的,不过现在大可不必太过惧怕IE8及早期浏览器了,毕竟它们正在消亡!

简单封装,兼顾一下IE8及早期浏览器:

  1. function addEvent(element, evnt, func){ 
  2.   if (element.attachEvent) // IE8及更低版本浏览器 
  3.    return element.attachEvent('on'+evnt, func); 
  4.   else // IE8+,或其它现代浏览器 
  5.    return element.addEventListener(evnt, func, false); 
  6. }; 
  7. //调用 
  8. addEvent(document.getElementById('element'),'click'
  9.     function () {  
  10.       // some code here 
  11.    } 
  12. ); 

性能对比

搜索了下知乎,以下供追求性能的程序员参考:

原生addEventListener比jq的on慢了60倍?(https://www.zhihu.com/question/56814906/answer/150530726)

 

相关经验

导读书签
书签初始化中…