事件模型

1、事件捕获和事件冒泡与事件委托三者的关系

事件冒泡和事件捕获分别由网景公式和微软公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题。事件捕获和冒泡是现在浏览器的执行事件的不同阶段,事件委托是利用冒泡阶段的运行机制来实现的

捕获、冒泡、事件委托关系图

事件冒泡和捕获的运行图

运行条件:当一个事件发生在具有父元素的元素上时,现代浏览器根据事件添加时的设置来执行(冒泡或者捕获)
通过addEventerListener()的第三个参数来设置事件是通过捕获阶段注册的(true),还是冒泡阶段注册的(false),默认情况下是false。

2、 事件冒泡

从实际操作的元素(事件)向父元素一级一级执行下去,直到达到<html>     

有的时候父元素和子元素都定义了click事件,但是不希望点击子元素的时候执行父元素的click事件,可以通过阻止冒泡(stopPropagation())在子元素上阻止冒泡。

3、事件捕获

浏览器检查元素的最外层祖先<html>,是否在捕获阶段注册了一个click事件处理程序,如果是,则运行它。 
然后,它移动到<html>的下一个元素(点击元素的父元素),并执行相同的操作,然后是下一个元素(点击的元 
素的父元素),以此类推,直到达到实际点击的元素。    

4、事件捕获和冒泡的区别

执行顺序不同
事件冒泡:事件会从最内层的元素开始发生,一直向上传播,直到document对象。
事件捕获:事件从最外层开始发生,直到最具体的元素。

5、事件委托使用场景

如果你想要在大量子元素中单击任何一个就可以执行一段代码,这个时候可以把事件监听器设置在父节点上。   
当事件捕获和事件冒泡同时存在的情况下,事件又是如何触发的呢?
<!--部分HTML代码-->  

<div id="s1">father
    <div id='s2'>children</div>
</div>
<!--部分JS代码-->  

s1.addEventListener("click",function(e){
    console.log('father的捕获事件')
},true);
s2.addEventListener("click",function(e){
    console.log('children的捕获事件')
},true);
s1.addEventListener("click",function(e){
    console.log('father的冒泡事件')
},false);
s2.addEventListener("click",function(e){
    console.log('children的冒泡事件')
},false);

打印结果:

father的捕获事件
children的捕获事件
children的冒泡事件
father的冒泡事件   

结论:
对于非target节点,则先执行捕获再执行冒泡,对于target节点则先执行先注册的事件,无论冒泡还是捕获。
先执行非target节点的捕获,然后根据注册顺序执行target节点的事件,然后再执行非target节点的冒泡。

addEventerListener,IE8及以下不支持,属于DOM2级的方法,可添加多个方法不被覆盖
解绑事件,参数和绑定相同

removeEventListener(event.type, handle, boolean);   

绑定事件兼容IE8及以下

attachEvent(event.type,handle);写事件名时要加上on前缀  ,IE特有,兼容IE8及以下,可添加多个事件处理程序,只支持冒泡阶段 

由于事件捕获阶段没有可以阻止事件的函数,所以一般都是设置为事件冒泡

6、阻止冒泡

e.stopPropagation()
stopPropagation是事件对象(Event)的一个方法,作用是阻止目标元素的冒泡事件,但是不会阻止默认行为。

兼容IE

e.cancelBubble = true   

阻止冒泡兼容IE写法

window.event?window.event.cancelBubble=true:e.stopPropagation();   
e && e.stopPropagation ? e.stopPropagation() : window.event.cancelBubble = true; 

7、取消默认事件

e.preventDefault()
preventDefault它也是事件对象的一个方法,作用是取消一个目标元素的默认行为,既然说是默认行为,当然只有它有默认行为才能被取消,如果元素本身无默认行为,调用当然无效啦,比如链接a,提交按钮input type="submit"等,当event对象的cancelable为false时,表示没有默认行为,这时即使有默认行为,调用preventDefault也是不会起作用的。
兼容IE: return false;
js的return false只会阻止默认行为,而是用jquery的话则既可以阻止默认行为,有防止对象冒泡。

8、总结使用方法 :

停止冒泡
function stopBubble(e){
     <!--如果提供了事件对象,则这是个非IE浏览器-->
    if(e&&e.stopPropagation){
        e.stopPropagation();
    }else{
        <!--我们需要使用IE的方式来取消事件冒泡-->
        window.event.cancelBubble = true;
    }
}  
阻止默认行为
function stopDefault(e){
    <!--阻止默认行为W3C-->
    if(e&&e.preventDefault()){
        e.preventDefault();
    }else{
        <!--IE中阻止默认行为-->
        return false;
    }
        
    }
}

9、事件注意点:

1、event代表事件的状态,例如触发event对象的元素,鼠标的位置及状态、按下的键等。
2、event对象只在事件发生的过程中才有效
firefox里的event和IE中的不同,IE里的是全局变量,随时可用,firefox里的要用参数引导才能用,是运行时的临时变量。
在IE/Opera中是window.event,在Firefox中是event;而事件的对象,在IE中是window.event.srcElement,在Firefox中是event.target,Opera中两者都可用。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,548评论 1 11
  • 事件是一种异步编程的实现方式,本质上是程序各个组成部分之间的通信。DOM支持大量的事件,本节介绍DOM的事件编程。...
    许先生__阅读 967评论 0 3
  • Dom事件 事件是一种异步编程的实现方式,本质上是程序各个组成部分之间的通信。DOM支持大量的事件 (一) Eve...
    woow_wu7阅读 1,812评论 0 1
  • 声明:本文来源于http://www.webzsky.com/?p=731我只是在这里作为自己的学习笔记整理一下(...
    angryyan阅读 7,133评论 1 6
  • 事件是一种异步编程的实现方式,本质上是程序各个组成部分之间的通信。DOM支持大量的事件,本节介绍DOM的事件编程。...
    周花花啊阅读 601评论 0 3