attachEvent(IE)与addEventListener(FF)
Mozilla中:
addEventListener的使用方式:
target.addEventListener(type, listener, useCapture);
target: 文档节点、document、window 或 XMLHttpRequest。
type: 字符串,事件名称,不含“on”,比如“click”、“mouseover”、“keydown”等。
listener :实现了 EventListener 接口或者是 JavaScript 中的函数。
useCapture :是否使用捕捉,一般用 false 。例如:document.getElementById("testText").addEventListener("keydown", function (event) { alert(event.keyCode); }, false);
IE中:
target.attachEvent(type, listener);
target: 文档节点、document、window 或 XMLHttpRequest。
type: 字符串,事件名称,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等。(不是事件,是事件句柄)
listener :实现了 EventListener 接口或者是 JavaScript 中的函数。 例如:document.getElementById("txt").attachEvent("onclick",function(event){alert(event.keyCode);});
(addEVentListener是w3c标准的event API但是ie不支持标准的capture bubble事件模型,所以只支持2参数的attachEvent不知是名字上的差别,addEventListener第三参数,如果是false那就是bubble过程的event handler如果是true那就是capture过程的event handler,而ie只支持bubble所以没必要添加第三参数,并且click是事件,而onclick是event handler不是有没有on的区别)
addEventListener 用于注册事件处理程序,IE 中为 attachEvent,我们为什么讲 addEventListener 而不讲 attachEvent 呢?一来 attachEvent 比较简单,二来 addEventListener 才是 DOM 中的标准内容。
简介
addEventListener 为文档节点、document、window 或 XMLHttpRequest 注册事件处理程序,在以前我们一般是 <input type="button" on
语法
target.addEventListener(type, listener, useCapture);
- target 文档节点、document、window 或 XMLHttpRequest。
- type 字符串,事件名称,不含“on”,比如“click”、“mouseover”、“keydown”等。
- listener 实现了 EventListener 接口或者是 JavaS
cript 中的函数。 - useCapture 是否使用捕捉,看了后面的事件流一节后就明白了,一般用 false。
示例
function Go()
{
//...
}
document.getElementById("testButton").addEventListener("click", Go, false);
或者 listener 直接就是函数
document.getElementById("testButton").addEventListener("click", function () { ... }, false);
addEventListener-事件流
说到 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-第三个参数 useCapture
addEventListener 有三个参数:第一个参数表示事件名称(不含 on,如 "click");第二个参数表示要接收事件处理的函数;第三个参数为 useCapture,本文就讲解它。
<div id="outDiv">
<div id="middleDiv">
<div id="inDiv">请在此点击鼠标。</div>
</div>
</div>
<div id="info"></div>
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);
上述是我们测试的代码,根据 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,则内层的触发先于外层。