JavaScript基础-事件传播机制

177 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第32天,点击查看活动详情

冒泡传播

触发当前元素的某一个事件(点击事件)行为,不仅当前元素事件行为触发,而且其祖先元素的相关事件行为也会依次被触发,这种机制就是“事件的冒泡传播机制”

image.png

window.onclick = function () {
  console.log("window");
};

document.onclick = function () {
  console.log("document");
};

document.documentElement.onclick = function () {
  console.log("html");
};

DOM0

  • xxx.onxxx=function(){} DOM0 事件绑定,给元素的事件行为绑定方法,这些方法都是在当前元素事件行为的冒泡阶段(或者目标阶段)执行的

  • xxx.addEventListener('xxx',function(){},false) 第三个参数 FALSE 也是控制绑定的方法在事件传播的冒泡阶段(或者目标阶段)执行;只有第三个参数为 TRUE 才代表让当前方法在事件传播的捕获阶段触发执行(这种捕获阶段执行没啥实际意义,项目中不用);

let aa = null;
document.body.onclick = function (ev) {
  console.log("body", ev, ev === aa); //=>TRUE
};

outer.onclick = function (ev) {
  console.log("outer", ev, ev === aa); //=>TRUE
};

inner.onclick = function (ev) {
  /*ev = ev || window.evenet;
    ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true;*/
  aa = ev;
  console.log("inner", ev);
};

祖先元素

  • 谷歌:window->document->html->body...
  • IE 高:window->html->body...
  • IE 低:html->body...

事件委托(事件代理)

利用事件的冒泡传播机制,如果一个容器的后代元素中,很多元素的点击行为(其它事件行为也是)都要做一些处理,此时我们不需要在像以前一样一个个获取一个个的绑定了,我们只需要给容器的 CLICK 绑定方法即可,这样不管点击的是哪一个后代元素,都会根据冒泡传播的传递机制,把容器的 CLICK 行为触发,把对应的方法执行,根据事件源,我们可以知道点击的是谁,从而做不同的事情即可

点击 a1,不仅触发 a1 的点击行为,而且 A 以及 CONTAINER 的点击行为都会被依次触发点击 b1-1,也是一样的,不仅 b1-1 的点击行为触发,而且 b1/B/CONTAINER 的点击行为也都会被依次触发

在此过程中,只给 CONTAINER 的点击事件行为绑定方法即可 ,不管点击的是后代中的谁,绑定的方法都会执行,而且 EV 事件对象中记录了事源(EV.TARGET)

let target = ev.target || ev.srcElement;
if(target.className==='al'){

}else

性能上提高

事件委托这种处理方式比一个个的事件绑定,性能上提高 50%左右,而且需要操作的元素越多,性能提高越大

image.png