事件流:阻止事件冒泡、阻止事件捕获preventDefault()、stopPropagation()、return false 之间的区别

参考文章:https://www.jb51.net/article/94394.htm


W3C 中定义事件的发生经历三个阶段:

捕获阶段(capturing)、目标阶段(targetin)、冒泡阶段(bubbling)

  • 冒泡型事件:当你使用事件冒泡时,子级元素先触发,父级元素后触发
  • 捕获型事件:当你使用事件捕获时,父级元素先触发,子级元素后触发
  • DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件

阻止事件发生的方法:

再谈事件函数执行先后顺序:

利用 addEventListener() 在元素上绑定多个事件,且设置不同的事件流。也就是说,先后绑定两个click 事件,一个设置事件冒泡,一个设置事件捕获

我们在outC上触发onclick事件(这个是目标对象),如果我们在outC上同时绑定捕获阶段/冒泡阶段事件处理函数会怎么样呢?


 

 

事件流:阻止事件冒泡、阻止事件捕获preventDefault()、stopPropagation()、return false 之间的区别_第1张图片

点击outC的时候,打印顺序是:capture1-->capture2-->target2-->target1-->bubble2-->bubble1。

捕获事件最后才绑定 ,但是最先执行了;然后是目标阶段的事件;最后是冒泡事件。

捕获事件 --> 目标阶段 --> 冒泡事件

由于outC是我们触发事件的目标对象,在outC上注册的事件处理函数,属于DOM事件流中的目标阶段。目标阶段函数的执行顺序:先注册的先执行,后注册的后执行。这就是上面我们说的,在目标对象上绑定的函数是采用捕获,还是采用冒泡,都没有什么关系,因为冒泡和捕获只是对父元素上的函数执行顺序有影响,对自己没有什么影响。如果不信,可以将下面的代码放进去验证。

// 目标(自身触发事件,是冒泡还是捕获无所谓)
    outC.addEventListener('click',function(){console.log("target1");},false);
    outC.addEventListener('click',function(){console.log("target2");},true);
    outC.addEventListener('click',function(){console.log("target3");},true);
    outC.addEventListener('click',function(){console.log("target4");},false);

事件流:阻止事件冒泡、阻止事件捕获preventDefault()、stopPropagation()、return false 之间的区别_第2张图片

至此我们可以给出事件函数执行顺序的结论了:捕获阶段的处理函数最先执行,其次是目标阶段的处理函数,最后是冒泡阶段的处理函数。目标阶段的处理函数,先注册的先执行,后注册的后执行。

 

 

 

 

你可能感兴趣的:(js)