事件冒泡:
IE 的事件流,事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。例如:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Event Bubbling Example</title> 5 </head> 6 <body> 7 <div id="myDiv">Click Me</div> 8 </body> 9 </html>
如果你单击了页面中的<div>元素,那么这个 click 事件会按照如下顺序传播:
(1) <div>
(2) <body>
(3) <html>
(4) document
事件捕获:
事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前捕获它。
前面的例子如果是事件捕获的话,那么单击<div>元素就会以下列顺序触发 click 事件:
(1) document
(2) <html>
(3) <body>
(4) <div>
“ DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。
以前面的例子为例,单击div后事件流过程是这样的:
HTML事件处理程序:
如果单击一个按钮执行事件的话,可以采用以下两种方式:
第一种: <input type="button" value="Click Me" onclick="alert(‘Clicked‘)" />
第二种:
1 <script type="text/javascript"> 2 function showMessage(){ 3 alert("Hello world!"); 4 } 5 </script> 6 <input type="button" value="Click Me" onclick="showMessage()" />
第二种方法创建了一个封装着元素属性值的函数,这个函数中有一个局部变量 event,也就是事件对象。通过 event 变量,可以直接访问事件对象,你不用自己定义它,也不用从函数的参数列表中读取。
例如查看事件的类型,可以通过event.type获得,单击事件输出类型为click。
在 HTML 中指定事件处理程序的缺点如下:
DOM0 级事件处理程序:
通过 JavaScript 指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。
要使用 JavaScript 指定事件处理程序,首先必须取得一个要操作的对象的引用。找到引用之后,将这个引用的属性的值设置为一个函数。
使用 DOM0 级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行;换句话说,程序中的 this 引用当前元素。例如:
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(){ 3 alert(this.id); //"myBtn" 4 };
如果想撤销事件,就将事件处理的属性设置为null就可以了,例如: btn.onclick = null; //删除事件处理程序
DOM2 级事件处理程序:
定义了两个方法,用于处理指定和删除事件处理程序的操作: addEventListener()和 removeEventListener()。
所有 DOM 节点中都包含这两个方法,并且它们都接受 3 个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是 true,表示在捕获
阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。
要在按钮上为 click 事件添加事件处理程序,可以使用下列代码::
1 var btn = document.getElementById("myBtn"); 2 btn.addEventListener("click", function(){ 3 alert(this.id); 4 }, false);
如果为同一元素定义了两个事件,这两个事件将会按照添加的顺序进行触发。
通过 addEventListener()添加的事件处理程序只能使用 removeEventListener()来移除,移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过 addEventListener()添加的匿名函数将无法移除。
1 var btn = document.getElementById("myBtn"); 2 btn.addEventListener("click", function(){ 3 alert(this.id); 4 }, false); 5 btn.removeEventListener("click", function(){ //没有用! 6 alert(this.id); 7 }, false);
但是下列代码就可以移除事件处理程序:
1 var btn = document.getElementById("myBtn"); 2 var handler = function(){ 3 alert(this.id); 4 }; 5 btn.addEventListener("click", handler, false); 6 //这里省略了其他代码 7 btn.removeEventListener("click", handler, false); //有效!
因为两个事件处理程序使用了相同的函数。
IE事件处理程序:
IE 实现了与 DOM 中类似的两个方法: attachEvent()和 detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。例如:
1 var btn = document.getElementById("myBtn"); 2 btn.attachEvent("onclick", function(){ 3 alert("Clicked"); 4 });
在 IE 中使用 attachEvent()与使用 DOM0 级方法的主要区别在于事件处理程序的作用域。在使用 DOM0 级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用 attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此 this 等于 window。例如:
1 var btn = document.getElementById("myBtn"); 2 btn.attachEvent("onclick", function(){ 3 alert(this === window); //true 4 });
用attachEvent()方法也可以用来为一个元素添加多个事件处理程序,这些事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发,先添加后执行。
使用 attachEvent()添加的事件可以通过 detachEvent()来移除,条件是必须提供相同的参数。同样匿名函数不能被删除,只能传入同一个引用。
跨浏览器的事件处理程序:
addHandler():视情况分别使用 DOM0 级方法、 DOM2 级方法或 IE 方法来添加事件。这个方法属于一个名叫 EventUtil 的对象,addHandler()方法接受 3 个参数:要操作的元素、事件名称和事件处理程序函数。
removeHandler():它也接受相同的参数。这个方法的职责是移除之前添加的事件处理程序——无论该事件处理程序是采取什么方式添加到元素中的,如果其他方法无效,默认采用 DOM0 级方法。
EventUtil类定义如下:
1 var EventUtil = { 2 addHandler: function(element, type, handler){ 3 if (element.addEventListener){ 4 element.addEventListener(type, handler, false); 5 } else if (element.attachEvent){ 6 element.attachEvent("on" + type, handler); 7 } else { 8 element["on" + type] = handler; 9 } 10 }, 11 removeHandler: function(element, type, handler){ 12 if (element.removeEventListener){ 13 element.removeEventListener(type, handler, false); 14 } else if (element.detachEvent){ 15 element.detachEvent("on" + type, handler); 16 } else { 17 element["on" + type] = null; 18 } 19 } 20 };
可以像下面这样使用EventUtil 对象:
1 var btn = document.getElementById("myBtn"); 2 var handler = function(){ 3 alert("Clicked"); 4 }; 5 EventUtil.addHandler(btn, "click", handler); 6 //这里省略了其他代码 7 EventUtil.removeHandler(btn, "click", handler);
事件对象:在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息。所有浏览器都支持 event 对象,但支持方式不同。
DOM中的事件对象:
event 对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。
举例:
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(event){ 3 alert(event.currentTarget === this); //true 4 alert(event.target === this); //true 5 };
以上代码检测了 currentTarget 和 target 与 this 的值。由于 click 事件的目标是按钮,因此这三个值是相等的。如果事件处理程序存在于按钮的父节点中(例如 document.body),那么这些值是不相同的。例如:
1 document.body.onclick = function(event){ 2 alert(event.currentTarget === document.body); //true 3 alert(this === document.body); //true 4 alert(event.target === document.getElementById("myBtn")); //true 5 };
当单击这个例子中的按钮时, this 和 currentTarget 都等于 document.body,因为事件处理程序是注册到这个元素上的。然而, target 元素却等于按钮元素,因为它是 click 事件真正的目标。由于按钮上并没有注册事件处理程序,结果 click 事件就冒泡到了 document.body,在那里事件才得到了处理。
event.preventDefault():阻止特定事件的默认行为。只有 cancelable 属性设置为 true 的事件,才可以使用 preventDefault()来取消其默认行为。例如,链接的默认行为就是在被单击时会导航到其 href 特性指定的 URL。如果你想阻止链接导航这一默认行为,那么通过链接的onclick 事件处理程序可以取消它。例如:
1 var link = document.getElementById("myLink"); 2 link.onclick = function(event){ 3 event.preventDefault(); 4 };
event.stopPropagation():用于立即停止事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡。例如:
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(event){ 3 alert("Clicked"); 4 event.stopPropagation(); 5 }; 6 document.body.onclick = function(event){ 7 alert("Body clicked"); 8 };
对于这个例子而言,如果不调用 stopPropagation(),就会在单击按钮时出现两个警告框。可是,由于 click 事件根本不会传播到 document.body,因此就不会触发注册在这个元素上的 onclick 事件处理程序。
event.eventPhase属性:可以用来确定事件当前正位于事件流的哪个阶段。如果是在捕获阶段调用的事件处理程序,那么 eventPhase 等于 1;如果事件处理程序处于目标对象上,则 eventPhase 等于 2;如果是在冒泡阶段调用的事件处理程序, eventPhase 等于 3。这里要注意的是,尽管“处于目标”发生在冒泡阶段,但 eventPhase 仍然一直等于 2。
IE中的事件对象:
要访问 IE 中的 event 对象有几种不同的方式,取决于指定事件处理程序的方法。
1 var btn = document.getElementById("myBtn"); 2 btn.onclick = function(){ 3 var event = window.event; 4 alert(event.type); //"click" 5 };
1 var btn = document.getElementById("myBtn"); 2 btn.attachEvent("onclick", function(event){ 3 alert(event.type); //"click" 4 });
<input type="button" value="Click Me" onclick="alert(event.type)">
event.srcElement属性 :事件的目标(与DOM中的target属性相同)。
event.returnValue属性:相当于 DOM 中的 preventDefault()方法。只要将 returnValue 设置为 false,就可以阻止默认行为。
event.cancelBubble属性:与 DOM 中的 stopPropagation()方法作用相同,都是用来停止事件冒泡的。由于 IE 不支持事件捕获,因而只能取消事件冒泡;但stopPropagatioin()可以同时取消事件捕获和冒泡。 将 cancelBubble 设置为 true,就可阻止事件通过冒泡而触发document.body 中注册的事件处理程序。
事件类型:
1 EventUtil.addHandler(window, "load", function(event){ 2 alert("Loaded!"); 3 });
第二种方式:为<body>元素添加一个 onload 特性,但这种方式只能添加一个事件处理程序。也可以用上述两种方式为图像等元素增加onload事件。
事件委托:
利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。例如, click 事件会一直冒泡到 document 层次。也就是说,我们可以为整个页面指定一个 onclick 事件处理程序,而不必给每个可单击的元素分别添加事件处理程序。
事件模拟:
原文:http://www.cnblogs.com/yangxiaoguai132/p/5188035.html