javascript addEventListener讲解

来源:互联网 发布:画平面示意图软件 编辑:程序博客网 时间:2024/05/30 04:20
对同一个事件添加多个处理程序有如下两种方法:
1、window.onload = function() {f(); f1(); f2(); ...} 2、if(window.addEventListener){ //firefox         window.addEventListener('load',f,false);         window.addEventListener('load',f1,false);         ...     }else{ //ie         window.attachEvent('onload',f);         window.attachEvent('onload',f1);         ...     }



说到 addEventListener 不得不说到事件流。当一个事件发生时,分为三个阶段:
  • 捕获阶段 从根节点开始顺序而下,检测每个节点是否注册了事件处理程序。如果注册了事件处理程序,并且 useCapture 为 true,则调用该事件处理程序。(IE 中无此阶段。)
  • 目标阶段 触发在目标对象本身注册的事件处理程序,也称正常事件派发阶段。
  • 冒泡阶段 从目标节点到根节点,检测每个节点是否注册了事件处理程序,如果注册了事件处理程序,并且 useCapture 为 false,则调用该事件处理程序。


举例:
<div id="div1">  <div id="div2">    <div id="div3">      <div id="div4">      </div>    </div>  </div></div>

如果在 d3 上点击鼠标,事件流是这样的:
  • 捕获阶段 在 div1 处检测是否有 useCapture 为 true 的事件处理程序,若有,则执行该程序,然后再同样地处理 div2。
  • 目标阶段 在 div3 处,发现 div3 就是鼠标点击的节点,所以这里为目标阶段,若有事件处理程序,则执行该程序,这里不论 useCapture 为 true 还是 false。
  • 冒泡阶段 在 div2 处检测是否有 useCapture 为 false 的事件处理程序,若有,则执行该程序,然后再同样地处理 div1。

注意,上述捕获阶段和冒泡阶段中,实际上 div1 之上还应该有结点,比如有 body,但这里不讨论。

addEventListener 有三个参数:第一个参数表示事件名称(不含 on,如 "click");第二个参数表示要接收事件处理的函数;第三个参数为 useCapture,本文就讲解它。
<div id="outDiv">  <div id="middleDiv">    <div id="inDiv">请在此点击鼠标。</div>  </div></div><div id="info"></div><script type="text/javascript">var outDiv = document.getElementById("outDiv");var middleDiv = document.getElementById("middleDiv");var inDiv = document.getElementById("inDiv");var info = document.getElementById("info");outDiv.addEventListener("click", function () { info.innerHTML += "outDiv" + "<br>"; }, false);middleDiv.addEventListener("click", function () { info.innerHTML += "middleDiv" + "<br>"; }, false);inDiv.addEventListener("click", function () { info.innerHTML += "inDiv" + "<br>"; }, false);</script>

上述是我们测试的代码,根据 info 的显示来确定触发的顺序,有三个 addEventListener,而 useCapture 可选值为 true 和 false,所以 2*2*2,可以得出 8 段不同的程序。
全为 false 时,触发顺序为:inDiv、middleDiv、outDiv;
全为 true 时,触发顺序为:outDiv、middleDiv、inDiv;
outDiv 为 true,其他为 false 时,触发顺序为:outDiv、inDiv、middleDiv;
middleDiv 为 true,其他为 false 时,触发顺序为:middleDiv、inDiv、outDiv;
……
最终得出如下结论:
  • true 的触发顺序总是在 false 之前;
  • 如果多个均为 true,则外层的触发先于内层;
  • 如果多个均为 false,则内层的触发先于外层。


下面提供全部代码,您可以更改其中的 true、false 值,来进行测试。注意,不适用于 IE。
<?xml version="1.0" encoding="gb2312"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Language" content="zh-cn" /><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><title>useCapture</title><style type="text/css">#outDiv{    padding:10px 10px 10px 10px;    border:1px solid red;}#middleDiv{    padding:10px 10px 10px 10px;    border:1px solid green;}#inDiv{    padding:10px 10px 10px 10px;    border:1px solid blue;}</style></head><body><div id="outDiv">  <div id="middleDiv">    <div id="inDiv">请在此点击鼠标。</div>  </div></div><div id="info"></div><script language="javascript" type="text/javascript"><!--var outDiv = document.getElementById("outDiv");var middleDiv = document.getElementById("middleDiv");var inDiv = document.getElementById("inDiv");var info = document.getElementById("info");outDiv.addEventListener("click", function () { info.innerHTML += "outDiv" + "<br>"; }, false);middleDiv.addEventListener("click", function () { info.innerHTML += "middleDiv" + "<br>"; }, false);inDiv.addEventListener("click", function () { info.innerHTML += "inDiv" + "<br>"; }, false);//--></script></body></html>
原创粉丝点击