js中关于事件捕获与事件冒泡的小实验

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

IE 5.5: div -> body -> document

IE 6.0: div -> body -> html -> document

Mozilla 1.0: div -> body -> html -> document -> window

 

2.事件捕获:事件从最不精确的对象(document 对象)开始触发,然后到最精确target

 

3.DOM事件流:同时支持事件捕获与事件冒泡,事件捕获发生在事件冒泡之前,DOM事件模型最独特的性质是,文本节点也触发事件(在IE中不会)。

下图是DOM事件流中的事件捕获与事件冒泡过程:

js中事件监听方法总共有三种,分别如下所示:

  • element.addEventListener(type, listener[, useCapture]); // IE6~8不支持
  • element.attachEvent(’on’ + type, listener); // IE6~10,IE11不支持
  • element[’on’ + type] = function(){} // 所有浏览器

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

 

传统的element[’on’ + type] = function(){}与addEventListener(event,fn,useCapture)区别在于element[’on’ + type] = function(){}无法进行事件捕获,并且element[’on’ + type] = function(){}不支持对同一个元素的同一个事件注册多个事件监听器,后定义的事件会覆盖先定义的事件。

 

4.事件捕获的小实验,代码如下:

实验一:

 1 <!doctype html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Document</title>
 6     <style type="text/css">
 7     body{
 8         background-color: yellow;
 9     }
10          
11          div{
12              background-color: red;
13              padding: 100px;
14          }
15          img{
16              padding: 50px;
17          }
18 
19     </style>
20 </head>
21 <body id="body">
22     <div id="div">
23          <img src="frame.gif" id="img" />
24     </div>
25     <script type="text/javascript">
26          function onBody(event){
27              console.log("event capture in body");
28              
29          }
30          function onDiv(event){
31              console.log("event capture in div");
32              event.bubbles=true;
33          }
34          function onImg(event){
35              console.log("event capture in img");
36              event.bubbles=true;
37          }
38          window.onload=function(){
39              var aimg=document.getElementById("img");
40              aimg.addEventListener("click",onImg);
41              var adiv=document.getElementById("div");
42              adiv.addEventListener("click",onDiv);
43              var abody=document.getElementById("body");
44              abody.addEventListener("click",onBody,true);
45          }
46     </script>
47 </body>
48 </html>

这是一个简单的小实验,其中定义了三个function,分别为onDiv,onImg,onBody,其中onBody的第三个参数定义为true,说明该函数在事件捕获时执行。

在Chrome浏览器下,单击img部分得到的结果如下:

由于单击事件最直接的target是img,onbody添加了事件捕获时执行的函数,所以会输出第一行,第二行是事件直接触发img上的事件,输出第二行,第三行是事件冒泡时执行了定义在div上的函数,输出第三行。

 

实验二:

如果将onBody的addEventListener的第三个参数不添加或者改成false,那么onBody的函数就会在事件冒泡时执行,得到如下结果:

 

posted on 2016-02-25 14:59  莫尤公子  阅读(1315)  评论(0编辑  收藏  举报

导航