js addEventListener绑定事件监听基础,用事件传播原理,理解事件监听函数执行顺序

dom.addEventListener(type, listener[, useCapture]) 定义一个特定事件的监听函数

dom.addEventListener(type, listener[, useCapture])用于在当前节点或对象上,定义一个特定事件的监听函数listener。一旦这个事件发生,会执行监听函数。该方法没有返回值。但是监听函数不是立即执行,有时根据useCapture (可以为false或true)值,在事件的冒泡(false,默认值)或捕获阶段(true)去执行。

该方法接受三个参数。

type:事件名称,大小写敏感。
listener:监听函数。事件发生时,会调用该监听函数。
useCapture:布尔值,表示监听函数是否在捕获阶段(capture)触发(参见后文《事件的传播》部分),默认为false(监听函数只在冒泡阶段被触发)。该参数可选。

<body>
    <div style="width:200px;height:50px;background:aliceblue" id="div">
        <button id="btn">点击</button>
    </div>
</body>
let div=document.getElementById("div"),btn=document.getElementById("btn");
//阻止事件冒泡,div事件不在冒泡阶段触发
 div.addEventListener("click",function(){console.log("div click");},true);//捕获阶段触发
btn.addEventListener("click",function(){console.log("btn click");});  //输出 div click; btn click
//以上dom接以下js
div.addEventListener("click",function(){console.log("div click");},false);//默认为false(监听函数只在冒泡阶段被触发)
btn.addEventListener("click",function(){console.log("btn click");});  //输出  btn click   div click  
证明事件传播是从window对象开始传播的
window.onclick=function(){
    console.log('window click');
}
div.addEventListener("click",function(){console.log("div click");},false);//默认为false(监听函数只在冒泡阶段被触发)
btn.addEventListener("click",function(){console.log("btn click");});  //输出  btn click   div click  window click

注意,浏览器总是假定click事件的目标节点,就是点击位置嵌套最深的那个节点(本例是

节点里面的节点)。所以,节点的捕获阶段和冒泡阶段,都会显示为target阶段。
同一个事件可以添加多个监听函数。

事件传播

一个事件发生后,会在子元素和父元素之间传播(propagation)
捕获阶段 window 到目标节点 在捕获中,外部元素的事件会先被触发,然后才会触发内部元素的事件 ,从window到目标节点事件依次触发
目标阶段 事件在目标节点触发
冒泡阶段 目标节点传回window对象 从底层传回上层
这种三阶段的传播模型,使得同一个事件会在多个节点上触发。
阻止事件传播 如果希望事件到某个节点为止,不再传播,可以使用事件对象的stopPropagation方法。
在此附上一个很丑但是很好理解记忆的事件传播图解…
js addEventListener绑定事件监听基础,用事件传播原理,理解事件监听函数执行顺序_第1张图片

事件对象 Event

事件发生以后,会产生一个事件对象 作为参数传给监听函数 浏览器原生提供一个Event对象,所有的事件都是这个对象的实例,或者说继承了Event.prototype对象。

function callback(event) {
  var tag = event.currentTarget.tagName;
  console.log('Tag: ' + tag); // 没有任何输出
}
div.addEventListener('click', callback, false);

Event生成实例

event = new Event("click");
Event {
    isTrusted: false
    bubbles: false
    cancelBubble: false
    cancelable: false
    composed: false
    currentTarget: null
defaultPrevented: false
eventPhase: 0
path:[]
returnValue: true
srcElement: null
target: null
timeStamp: 3540258.5
type: "click"
[[Prototype]]: Event
}

综合事件传播,理解event的两个属性 Event.currentTarget,Event.target

以下猜猜输出顺序

<body>
   <div id="div">
       <button id="btn">点击</button>
   </div>
</body>
   let btn=$("#btn")[0],div=$("#div")[0];
   //btn.addEventListener("click",true);
   //这样写报错,要求第二个参数为对象Uncaught TypeError: Failed to execute 'addEventListener' on 'EventTarget': parameter 2 is not of type 'Object'
   //点击btn  ,默认冒泡
   div.addEventListener("click",function(event){
       console.log('div click');
   },false)//父元素监听函数是冒泡阶段执行
   btn.addEventListener("click",function(event){//看路径,看何时触发
       console.log("btn click");
       },true);//如果是true的话,事件直接到btn  子元素监听函数是捕获阶段执行

结果是 btn click div click
我一开始以为是div click btn click ,因为感觉子元素是事件捕获时触发的,而父元素(div)click被触发先于子元素(btn),其实是错的,根本原因在于,事件被触发时,监听函数不一定马上执行,监听函数执行时间也因为受ad listener,第三个参数决定。
这里父元素的为false,父元素监听函数在冒泡阶段执行的,子元素的第三个参数true 是表示子元素事件的监听函数 是在捕获阶段执行的
这个案例的核心说明了:事件 被触发了之后 ,如果用Addeventlistener 给元素绑定事件监听函数的话 ,它的监听函数不一定随着事件触发立即执行,涵盖了 Addeventlistener 绑定事件监听函数和事件传播原理。
参考 (阮一峰老师的事件教程 ) https://www.bookstack.cn/read/javascript-tutorial/docs-events-model.md

你可能感兴趣的:(js,javascript,前端,开发语言)