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方法。
在此附上一个很丑但是很好理解记忆的事件传播图解…
在这里插入图片描述

事件对象 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

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值