<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>Examples</title> <meta name="description" content=""> <meta name="keywords" content=""> <link href="" rel="stylesheet"> <style> #father{ 300px; height: 300px; margin: 0 auto; border: 1px solid #000; } #son{ 100px; height: 100px; margin: 0 auto; border: 1px solid #000; } </style> </head> <body> <div id="father"> <div class="c" id="son"></div> </div> </body> <script> var father=document.getElementById("father"); father.addEventListener("click",function(e){ console.log(e.eventPhase); console.log(e.target); console.log("father");
},true) father.addEventListener("click",function(e){ console.log(e.eventPhase); console.log(e.target); console.log("father");
},false) var son=document.getElementById("son"); son.addEventListener("click",function(e){ console.log("son"); console.log(e.eventPhase); }) </script> </html>
首先贴一下代码,大家创建一个任意的html文件,比如a.html,然后把这段代码放进去。
用chrome浏览器打开,并审查元素,最后界面如下:
这里给了两个层,一个id=father,就是最外层,另一个id=son 就是最里层。
顺便简单介绍下浏览器的事件传递类型。
微软和早期的网景分别使用了事件冒泡和事件捕获,然后形成现在浏览器的事件机制。
事件冒泡就是说我点击son后,son先接收这个事件信息,然后传递给father,
事件捕获恰恰相反,先是father接收事件,然后是son。
然后es(就是标准js,ecma java script)规定的事件传递顺序是先捕获,再到事件处理,再到冒泡阶段。
那这样是不是说我一个点击事件发生后,先经过father,然后到son处理,再冒泡到father呢?
我们知道DOM2针对元素监听的方法是xx.addEventListener("事件名","处理函数","是否捕获")
默认情况下第三个参数是false,也就是不捕获而只冒泡。
返回我们的代码,可以看到我这里对father写了两个监听函数,一个是捕获,一个是冒泡,那么接下来让我们单击里层元素看看发生什么。
可以看到按顺序输出1,2,3以及在两个father处理函数输出事件对象,也就是son。
我在监听函数里写的console.log(e.eventPhase),这个是标示事件处理阶段
1-捕获 2-处理 3 冒泡
因此这里按照顺序输出。证明浏览器遵循的就是这个原则,当然我们平时写事件监听不会针对同一个元素的事件写两个处理顺序不同的处理函数,通常写的都是基于冒泡的。
因此我们把第二个监听函数去掉再看看
发现只有2 ,3输出,再次印证这个事实。
事件冒泡的机理可以让我们写事件委托来替代针对某元素内在相同的n个元素写监听函数。事件委托介绍我稍后再给大家。