JS事件冒泡、事件捕获、事件委托

过去的,未来的
2020-04-28 / 0 评论 / 0 点赞 / 768 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2020-04-29,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

参考资料

事件冒泡

微软提出,嵌套元素触发事件,从内向外执行代码

在p元素上发生click事件的顺序应该是==p -> div -> body -> html -> document==

<div id="s1">s1
  <div id="s2">s2</div>
</div>
<script>
// 点击s1 - s1 冒泡事件
// 点击s2 - s2 冒泡事件 s1 冒泡事件
s1.addEventListener("click",function(e){
    console.log("s1 冒泡事件");
},false); 

s2.addEventListener("click",function(e){
    console.log("s2 冒泡事件");
},false); 
</script>

事件捕获

网景公司提出,嵌套元素触发事件,从外层开始直到具体元素

在p元素上发生click事件的顺序应该是==document -> html -> body -> div -> p==

<div id="s1">s1
  <div id="s2">s2</div>
</div>
<script>
// 点击s1 - s1 捕获事件
// 点击s2 - s1 捕获事件 s2 捕获事件
s1.addEventListener("click",function(e){
    console.log("s1 捕获事件");
},true);
s2.addEventListener("click",function(e){
    console.log("s2 捕获事件");
},true);
</script>

!!!w3c规定先捕获再冒泡

addEventListener(event, callback, useCapture)

  • 第一个参数是需要绑定的事件
  • 第二个参数是触发事件后要执行的函数
  • 第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。

如果冒泡和捕获同时存在?

  • 对于非target节点则先执行捕获在执行冒泡
  • 对于target节点则是先执行先注册的事件,无论冒泡还是捕获
<div id="s1">s1
  <div id="s2">s2</div>
</div>
<script>
// 事件冒泡
// 点击s1 s1 冒泡事件 s1 捕获事件 (按照注册顺序)
// 点击s2 s1 捕获事件 s2 冒泡事件 s2 捕获事件 s1 冒泡事件
s1.addEventListener("click",function(e){
    console.log("s1 冒泡事件");
},false);
s2.addEventListener("click",function(e){
    console.log("s2 冒泡事件");
},false); 
// 事件捕获
s1.addEventListener("click",function(e){
    console.log("s1 捕获事件");
},true); 
s2.addEventListener("click",function(e){
    console.log("s2 捕获事件");

阻止事件冒泡

  • e.stopPropagation() 【非ie】
  • e.cancelBubble = true 【ie】

阻止默认事件

  • e.preventDefault() 【谷歌及IE8以上】
  • window.event.returnValue = false 【IE8以下无兼容问题(但不能用于节点直接onclick绑定函数)】
  • return false;

事件委托

事件委托也称为事件代理利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

/**
 * @param eventType:String,事件类型
 * @param element:DOM element,目标元素
 * @param callback:Function,业务事件处理程序
 */ 
function eventHandler(eventType, element, callback) {
  document.addEventListener(eventType, function(e){
    if(e.target === element) {
      callback.call(this);
    }
  }, false);
}

0

评论区