事件:用户或者浏览器自身执行的某种动作,例如click,load,mouseover等。
事件处理程序:响应某个事件的函数。事件处理程序的名字以"on"开头。因此click事件的事件处理程序就是onclick,load事件的事件处理程序就是onload。
为事件指定事件处理程序的方式有好几种:
1. HTML事件处理程序
一般不用。
2. DOMLevel0级事件处理程序(所有浏览器均支持)
首先必须取得要操作的对象的引用:
var btn = document.getElementById("myBtn"); btn.onclick = function(){ alert("clicked"); };
DOMLevel0事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在所操作的元素的作用域内运行,所以this引用当前元素:
var btn = document.getElementBy("myBtn"); btn.onclick = function(){ alert(this.getAttribute("id"));
alert(this.id); };
上面的例子获取了元素的id,当然还可以通过this访问元素的任何属性和方法,访问元素属性可以通过下面两种方法:
- this.propertyName
- this.getAttribute(propertyName)
访问元素的方法目前我只知道通过this.methodName来访问。
那么如何删除DOMLevel0事件处理程序呢?
btn.onclick = null; //删除事件处理程序
将事件处理程序设置为null后,再单击按钮将不会有任何动作发生。
DOMLevel0事件处理程序会在事件流的冒泡阶段被处理。
3. DOMLevel2事件处理程序(>=IE9, FireFox, Safari, Chrome, Opera)
DOMLevel2事件处理程序定义了两个方法:
- addEventListener(eventName, functionName, true/false)
- removeEventListener(eventName, functionName, true/false)
分别用来添加事件处理程序和删除事件处理程序。三个参数分别是:事件名,事件处理函数,捕获(true)还是冒泡(false)阶段处理该事件。
下面这里例子说明了设置为捕获跟冒泡的区别:
<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> div { width: 100px; height: 50px; background-color: gray; } </style> </head> <body> <div id="div1"> <div id="div2"> <div id="div3"></div> </div> </div> <script type="text/javascript"> var div1 = document.getElementById("div1"); var div2 = document.getElementById("div2"); var div3 = document.getElementById("div3"); div1.addEventListener("click", function(){ alert("div1"); }, false); div2.addEventListener("click", function(){ alert("div2"); }, false); div3.addEventListener("click", function(){ alert("div3"); }, false); </script> </body> </html>
通过addEventListener()添加的事件处理程序只能通过removeEventListener()来移除,移除时传入的参数与添加事件处理程序时使用的参数必须相同,通过addEventListener()添加的匿名函数将无法移除,如果想随后移除某个事件处理程序,则添加事件处理程序的时候要注意使用有名函数:
var btn = document.getElementById("myBtn"); var handler = function(){ alert(this.id); }; btn.addEventListener("click", handler, false); //这里省略了其他代码 btn.removeEventListener("click", handler, false);
3. IE事件处理程序(<=IE8)
IE实现了与DOMLevel2类似的两个方法:
- attachEvent(eventHandlerName, functionName)
- detachEvent(eventHandlerName, functionName)
四点与DOMLevel2不同的地方需要注意:
- 添加到冒泡阶段
- 第一个参数是eventHandlerName("onclick"),而不是eventName("click")
- 事件处理程序在全局作用域内运行,所以this指向window(编写跨浏览器代码时需要注意)
- 多次添加同一个事件处理程序时,后添加的先执行
4. 使事件处理程序能够跨浏览器
DOMLevel0和IE事件处理程序都会添加到冒泡阶段,因此要保证处理事件的代码能够在大多数浏览器下一致的运行,只需关注冒泡阶段。下面创建EventUtil对象来处理浏览器之间的差异。EventUtil对象包含两个方法:
- addHandler(element, eventName, functionName)
- removeHandler(element, eventName, functionName)
var EventUtil = { addHandler: function(element, eventName, handler){ if(element.addEventListener){ element.addEventListener(eventName, handler, false);//添加到冒泡阶段 } else if(element.attachEvent){ element.attachEvent("on" + eventName, handler); } else { element["on" + eventName] = handler; } }, removeHandler: function(element, eventName, handler){ if(element.removeEventListener){ element.removeEventListener(eventName, handler, false); } else if(element.detachEvent){ element.detachEvent("on" + eventName, handler); } else { element["on" + eventName] = null; } } };
调用该API的方式如下:
function handler(){ alert("clicked"); } EventUtil.addHandler(div1, "click", handler); EventUtil.removeHandler(div1, "click", handler);
注意:为了避免IE中事件处理程序的作用域问题,上面handler函数中不能出现this引用。