JavaScript应用核心:事件处理概述(1)(3)
跨浏览器的注册与移除元素事件监听器方案
我们现在已经知道,对于支持addEventListener方法的浏览器,只要需要事件监听器脚本就都需要调用addEventListener方法;而对于不支持该方法的IE浏览器,使用事件监听器时则需要调用attachEvent方法。
要确保浏览器使用正确的方法其实并不困难,只需要通过一个if-else语句来检测当前浏览器中是否存在addEventListener方法或attachEvent方法即可。这样的方式就可以实现一个跨浏览器的注册与移除元素事件监听器方案:
- var EventUtil = {
- //注册
- addHandler: function(element, type, handler){
- if (element.addEventListener){
- element.addEventListener(type, handler, false);
- } else if (element.attachEvent){
- element.attachEvent("on" + type, handler);
- } else {
- element["on" + type] = handler;
- }
- },
- //移除注册
- removeHandler: function(element, type, handler){
- if (element.removeEventListener){
- element.removeEventListener(type, handler, false);
- } else if (element.detachEvent){
- element.detachEvent("on" + type, handler);
- } else {
- element["on" + type] = null;
- }
- }
- };
事件对象引用
为了更好的处理事件,你可以根据所发生的事件的特定属性来采取不同的操作。如事件模型一样,IE 和其他浏览器处理方法不同:IE 使用一个叫做 event 的全局事件对象来处理对象(它可以在全局变量window.event中找到),而其它所有浏览器采用的 W3C 推荐的方式,则使用独立的包含事件对象的参数传递。
跨浏览器实现这样的功能时,最常见的问题就是获取事件本身的引用及获取该事件的目标元素的引用。下面这段代码就为你解决了这个问题:
- var EventUtil ={
- getEvent: function(event){
- return event ? event : window.event;
- },
- getTarget: function(event){
- return event.target || event.srcElement;
- }
- };
停止事件冒泡和阻止事件的默认行为
“停止事件冒泡“和”阻止浏览器的默认行为“,这两个概念非常重要,它们对复杂的应用程序处理非常有用。
1.停止事件冒泡
停止事件冒泡是指,停止冒泡型事件的进一步传递(取消事件传递,不只是停止IE和DOM标准共有的冒泡型事件,我们还可以停止支持DOM标准浏览器的捕捉型事件,用topPropagation()方法)。例如上图中的冒泡型事件传递中,在body处理停止事件传递后,位于上层的document的事件监听器就不再收到通知,不再被处理。
2.阻止事件的默认行为
停止事件的默认行为是指,通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作)。例如,如果表单中input type 属性是 “submit”,点击后在事件传播完浏览器就自动提交表单。又例如,input 元素的 keydown 事件发生并处理后,浏览器默认会将用户键入的字符自动追加到 input 元素的值中。
停止事件冒泡的处理方法:
在IE下,通过设置event对象的cancelBubble为true即可。
- function someHandle() {
- window.event.cancelBubble = true;
- }
- DOM标准通过调用event对象的stopPropagation()方法即可。
- function someHandle(event) {
- event.stopPropagation();
- }
因些,跨浏览器的停止事件传递的方法是:
- function someHandle(event) {
- eventevent = event || window.event;
- if(event.stopPropagation){
- event.stopPropagation();
- }else {
- event.cancelBubble = true;
- }
- }
阻止事件的默认行为的处理方法:
就像事件模型和事件对象差异一样,在IE和其它所有浏览器中阻止事件的默认行为的方法也不同。在IE下,通过设置event对象的returnValue为false即可。
- function someHandle() {
- window.event.returnValue = false;
- }
DOM标准通过调用event对象的preventDefault()方法即可。
- function someHandle(event) {
- event.preventDefault();
- }
因些,跨浏览器的取消事件传递后的默认处理方法是:
- function someHandle(event) {
- eventevent = event || window.event;
- if(event.preventDefault){
- event.preventDefault();
- }else{
- event.returnValue = false;
- }
- }
完整的事件处理兼容性函数
- var EventUtil = {
- addHandler: function(element, type, handler){
- if (element.addEventListener){
- element.addEventListener(type, handler, false);
- } else if (element.attachEvent){
- element.attachEvent("on" + type, handler);
- } else {
- element["on" + type] = handler;
- }
- },
- removeHandler: function(element, type, handler){
- if (element.removeEventListener){
- element.removeEventListener(type, handler, false);
- } else if (element.detachEvent){
- element.detachEvent("on" + type, handler);
- } else {
- element["on" + type] = null;
- }
- },
- getEvent: function(event){
- return event ? event : window.event;
- },
- getTarget: function(event){
- return event.target || event.srcElement;
- },
- preventDefault: function(event){
- if (event.preventDefault){
- event.preventDefault();
- } else {
- event.returnValue = false;
- }
- },
- stopPropagation: function(event){
- if (event.stopPropagation){
- event.stopPropagation();
- } else {
- event.cancelBubble = true;
- }
- }
- };






