跨浏览器的事件处理程序

     为了以跨浏览器的方式处理事件,不少开发人员会使用能够隔离浏览器差异的 JavaScript 库,还有 一些开发人员会自己开发合适的事件处理的方法。自己编写代码其实也不难,只要恰当地使用能力检测即可(能力检测在第 9 章介绍过)。要保证处理事件的代码能在大多数浏览器下一致地运行,只需关 注冒泡阶段.

     第一个要创建的方法是 addHandler(),它的职责是视情况分别使用 DOM0 级方法、DOM2 级方 法或 IE方法来添加事件。这个方法属于一个名叫 EventUtil 的对象,本书将使用这个对象来处理浏览 器间的差异。addHandler()方法接受 3个参数:要操作的元素、事件名称和事件处理程序函数。 与 addHandler()对应的方法是 removeHandler(),它也接受相同的参数。这个方法的职责是移 除之前添加的事件处理程序——无论该事件处理程序是采取什么方式添加到元素中的,如果其他方法无 效,默认采用 DOM0级方法

  <script>    const EventUtil ={      addhandler:(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        }      },      removerHandler:(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        }      }    }  </script>
复制代码

这两个方法首先都会检测传入的元素中是否存在 DOM2级方法。如果存在 DOM2级方法,则使用 该方法:传入事件类型、事件处理程序函数和第三个参数 false(表示冒泡阶段)。如果存在的是 IE的 方法,则采取第二种方案。注意,为了在 IE8及更早版本中运行,此时的事件类型必须加上"on"前缀。 后一种可能就是使用 DOM0级方法(在现代浏览器中,应该不会执行这里的代码)。此时,我们使用 的是方括号语法来将属性名指定为事件处理程序,或者将属性设置为 null。

跨浏览器的事件对象 

虽然 DOM和 IE中的 event 对象不同,但基于它们之间的相似性依旧可以拿出跨浏览器的方案来。 IE 中 event 对象的全部信息和方法 DOM 对象中都有,只不过实现方式不一样。不过,这种对应关系 让实现两种事件模型之间的映射非常容易。可以对前面介绍的 EventUtil 对象加以增强,添加如下方 法以求同存异。 

<script>    const EventUtil ={      addhandler:(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        }      },      removerHandler:(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:(event)=> {        return evnet? event:window.event;      },      getTarget:(event)=>{        return event.target || event.srcElement;      },      preventDefault (event) {        if(event.preventDefault){          event.preventDefault()        } else {          event.returnValue = false        }      },      stopPropagation :(event)=>{        if(event.stopPropagation) {          event.stopPropagation();        } else {          event.cancelBulle = true;        }      }    }  </script>复制代码

第一个是 getEvent(),它返回对 event 对象的引用。考虑到 IE中事件对象的位置不同,可以使用这个方法来取得 event 对象,而不必担心指 定事件处理程序的方式。在使用这个方法时,必须假设有一个事件对象传入到事件处理程序中,而且要 把该变量传给这个方法,如下所示。

btn.onclick = function(event){     event = EventUtil.getEvent(event); }; 
复制代码

在兼容 DOM的浏览器中,event 变量只是简单地传入和返回。而在 IE中,event 参数是未定义 的(undefined),因此就会返回 window.event。将这一行代码添加到事件处理程序的开头,就可以确 保随时都能使用 event 对象,而不必担心用户使用的是什么浏览器。 

第二个方法是 getTarget(),它返回事件的目标。在这个方法内部,会检测 event 对象的 target 属性,如果存在则返回该属性的值;否则,返回 srcElement 属性的值。

btn.onclick = function(event){event = EventUtil.getEvent(event);   var target = EventUtil.getTarget(event); }; 复制代码

第三个方法是 preventDefault(),用于取消事件的默认行为。在传入 event 对象后,这个方法 会检查是否存在 preventDefault()方法,如果存在则调用该方法。如果 preventDefault()方法不 存在,则将 returnValue 设置为 false。下面是使用这个方法的例子

var link = document.getElementById("myLink"); link.onclick = function(event){     event = EventUtil.getEvent(event);     EventUtil.preventDefault(event); }; 
复制代码

以上代码可以确保在所有浏览器中单击该链接都不会打开另一个页面。首先,使用 EventUtil. getEvent()取得 event 对象,然后将其传入到 EventUtil.preventDefault()以取消默认行为。

第四个方法是 stopPropagation(),其实现方式类似。首先尝试使用 DOM方法阻止事件流,否 则就使用 cancelBubble 属性。下面看一个例子

var btn = document.getElementById("myBtn"); 

btn.onclick = function(event){ alert("Clicked"); 

 event = EventUtil.getEvent(event); 

 EventUtil.stopPropagation(event); }; 

 document.body.onclick = function(event){ alert("Body clicked"); };


首先使用 EventUtil.getEvent()取得了 event 对象,然后又将其传入到 EventUtil. stopPropagation()。别忘了由于 IE不支持事件捕获,因此这个方法在跨浏览器的情况下,也只能用 来阻止事件冒泡。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值