js之事件冒泡和事件捕获

今天看到阿里的一道面试题:

  • 如果给一个元素绑定了4个事件处理(用addEventListener),其中两个是capture, 两个冒泡,那么触发顺序是什么?

看完之后开始找答案,然后写个栗子测试了一下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div>
        <input type="button" id="btn_test" value="测试" /> 
    </div>
    <script>
        window.onload=function(){ 
            var oBtn = document.getElementById("btn_test");
             if (oBtn.attachEvent) { //IE 中
                oBtn.attachEvent("onclick",test1);
                oBtn.attachEvent("onclick",test2);  
                oBtn.attachEvent("onclick",test3);
                oBtn.attachEvent("onclick",test4); 
            }
            else{
                oBtn.addEventListener("click",test1,false);//冒泡
oBtn.addEventListener("click",test2,false); //冒泡
oBtn.addEventListener("click",test3,true);//捕获
oBtn.addEventListener("click",test4,true); //捕获
} function test1(){ console.log("test1") } function test2(){ console.log("test2") } function test3(){ console.log("test3") } function test4(){ console.log("test4") } } </script> </body> </html>

测试结果如下:

ie6:结果是随机的;

ie7-8结果如下图:

ie9结果如下图:

非ie浏览器结果如下:

由于ie7~ie9测试结果我是用浏览器模拟的,不确定这几种浏览器版本的结果准确性,由此可看,执行顺序应该是这样的:

捕获比冒泡先触发,但同级哪个函数先触发,不同浏览器有差异。非IE浏览器是按照绑定顺序执行,IE好像是随机(ps:我在js高级程序设计一书中中看到是这样说的----这些事件处理程序不是已添加它们的顺序执行,而是以相反的顺序被触发)。

下面我对如上知识做一下补充:

(1)冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。

(2)捕获型事件(event capturing):事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)。

(3)DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件,但是,捕获型事件先发生。两种事件流会触及DOM中的所有对象,从document对象开始,也在document对象结束。

支持W3C标准的浏览器在添加事件时用addEventListener(event,fn,useCapture)方法,基中第3个参数useCapture是一个Boolean值,用来设置事件是在事件捕获时执行,还是事件冒泡时执行。而不兼容W3C的浏览器(IE)用attachEvent()方法,此方法没有相关设置,不过IE的事件模型默认是在事件冒泡时执行的,也就是在useCapture等于false的时候执行,所以把在处理事件时把useCapture设置为false是比较安全,也实现兼容浏览器的效果。

事件捕获阶段:事件从最上一级标签开始往下查找,直到捕获到事件目标(target)。

事件冒泡阶段:事件从事件目标(target)开始,往上冒泡直到页面的最上一级标签。

//冒泡
posted @ 2015-08-31 15:29  imsomnus  阅读(661)  评论(0编辑  收藏  举报