JS 事件(2)——事件处理程序
事件处理程序
事件是用户或浏览器自身执行的某种操作,如click、mouseover;响应某个事件的函数就是事件处理程序(或事件侦听器),如onclick、onmouseover。
HTML事件处理程序
某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML属性来指定,这个属性的值应该是能够执行的JavaScript代码。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>HTML事件处理程序</title> 6 </head> 7 <body> 8 <div id="box"> 9 <input type="button" id="btn" value="button" onclick="showMessage()"> 10 </div> 11 <script type="text/javascript"> 12 function showMessage() { 13 alert("You've clicked the button."); 14 }; 15 </script> 16 </body> 17 </html>
HTML事件处理程序最大的缺点,HTML与Javascript代码紧密耦合。
DOM0级事件处理程序
通过Javascript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性,
每个元素(包括window和document)都有自己的事件处理程序属性;将这些属性的值设置为一个函数,就可以指定事件处理程序。
使用DOM0级方法指定的事件处理程序被认为是元素的方法;因此,事件处理程序是在元素的作用域中运行的;换句话说,程序中的this引用当前元素。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>DOM0级事件处理程序</title> 6 </head> 7 <body> 8 <div id="box"> 9 <input type="button" id="btn" value="button"> 10 </div> 11 <script type="text/javascript"> 12 function showId() { 13 alert(this.id); 14 }; 15 var btn = document.getElementById("btn"); 16 btn.onclick = showId; 17 </script> 18 </body> 19 </html>
注意:将函数赋值给一个属性,btn.onclick = showId;NO圆括号!!!
也可以删除通过DOM0级方法指定的事件处理程序,将其属性值设置为null即可。
1 btn.onclick = null;
DOM2级事件处理程序
“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。
所有DOM节点中都包含这两个方法,并且它们都接收三个参数:事件处理程序名称(“click”)、事件处理程序函数、布尔值。
对于布尔值参数,如果为true,表示在捕获阶段调用事件处理程序;如果为false,表示在冒泡阶段调用事件处理程序。大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段。
使用DOM0级方法或DOM2级方法,能够在一个节点上添加多个事件,也可以添加多个事件处理程序。
与DOM0级方法一样,DOM2级方法添加的事件处理程序也是在其依附的元素的作用域中运行,this引用当前元素。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>DOM2级事件处理程序</title> 6 </head> 7 <body> 8 <div id="box"> 9 <input type="button" id="btn" value="button"> 10 </div> 11 <script type="text/javascript"> 12 function showMessage() { 13 alert("You've clicked me!"); 14 }; 15 function showId() { 16 alert(this.id); //btn 17 }; 18 var btn = document.getElementById("btn"); 19 btn.addEventListener("click", showMessage, false); 20 btn.addEventListener("click", showId, false); 21 </script> 22 </body> 23 </html>
通过addEventListener()添加的事件处理程序,只能通过removeEventListener()方法移除;移除时传入的参数与添加时传入的参数相同。
1 btn.removeEventListener("click", showMessage, false); 2 btn.removeEventListener("click", say, false);
通过addEvenntListener()添加的匿名函数无法移除。
1 <script type="text/javascript"> 2 var btn = document.getElementById("btn"); 3 btn.addEventListener("click", function() { 4 alert("You've clicked me!"); 5 }, false); 6 btn.removeEventListener("click", function() { //移除无效 7 alert("You've clicked me!"); 8 }, false); 9 </script>
IE9、Safari、Chrome、Firefox和Opera支持DOM2级事件处理程序。
IE事件处理程序
IE9支持“DOM2级”事件;在IE8及其更早版本,IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。
这两个方法都接收两个参数:事件处理程序名称(“onclick”)、事件处理程序函数。
由于IE8及其更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。
在IE中使用DOM0级方法与使用attachEvent()方法的主要区别在于事件处理程序的作用域。使用DOM0级方法,如前所述,事件处理程序会在其所属元素的作用域中运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this指向window对象。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>IE中的事件处理程序</title> 6 </head> 7 <body> 8 <div id="box"> 9 <input type="button" id="btn" value="button"> 10 </div> 11 <script type="text/javascript"> 12 function showMessage() { 13 alert("You've clicked me!"); 14 }; 15 function showId() { 16 alert(this.id); //undefined 17 alert(this === window); //true 18 }; 19 var btn = document.getElementById("btn"); 20 btn.attachEvent("onclick", showMessage); 21 btn.attachEvent("onclick", showId); 22 </script> 23 </body> 24 </html>
跨浏览器的事件处理程序
使用能力检测,如果支持“DOM2级”方法,则使用该方法;如果支持IE方法,则使用IE方法;如果两者都不支持,则使用“DOM0级”方法。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>跨浏览器的事件处理程序</title> 6 </head> 7 <body> 8 <div id="box"> 9 <input type="button" id="btn" value="button"> 10 </div> 11 <script type="text/javascript"> 12 var event_util = { 13 //添加事件 14 addHandler: function(element, type, handler) { //三个参数:元素、事件、事件处理程序 15 if(element.addEventListener) { //如果支持"DOM2级"方法,则使用该方法 16 element.addEventListener(type, handler, false); 17 } else if(element.attachEvent) { //如果支持IE方法,则使用IE方法 18 element.attachEvent("on" + type, handler); 19 } else { 20 element["on" + type] = handler; //如果以上都不支持,则使用"DOM0级"方法 21 } 22 }, 23 //移除事件 24 removeHandler: function(element, type, handler) { 25 if(element.removeEventListener) { 26 element.removeEventListener(type, handler, false); 27 } else if(element.detachEvent) { 28 element.detachEvent("on" + type, handler); 29 } else { 30 element["on" + type] = null; 31 } 32 } 33 }; 34 function showMessage() { 35 alert("You've clicked the button."); 36 }; 37 var btn = document.getElementById("btn"); 38 event_util.addHandler(btn, "click", showMessage); //添加事件 39 event_util.removeHandler(btn, "click", showMessage); //移除事件 40 </script> 41 </body> 42 </html>
由于IE中的事件处理程序this指向的window对象,而"DOM2级"事件处理程序与DOM0级事件处理程序中的this引用当前元素;在编写跨浏览器的代码时,对于this的使用一定要慎重。

浙公网安备 33010602011771号