.
  • 前言:什么是EventUtil?.
  • EventUtil对象全见.
  • addHandler方法.
  • removeHandler方法.
  • event对象与getEvent方法.
  • target对象与getTarget方法.
  • preventDefault方法.
  • stopPropagation方法.
  • “相关元素”与getRelatedTarget方法.
  • getButton方法.
  • getWheelDelta方法.
  • getCharCode方法.
  • 留言评论
  • 返回顶部

前言:什么是EventUtil?

在JavaScript中,DOM0级、DOM2级与旧版本IE(8-)为对象添加事件的方法不同

为了以跨浏览器的方式处理事件,需要编写一段“通用代码”,即跨浏览器的事件处理程序

习惯上,这个方法属于一个名为EventUtil的对象

编写并使用该对象后,可保证处理事件的代码能在大多数浏览器下一致的运行

本文将围绕着EventUtil对象展开,并提供该通用对象代码以作参考分享

文章主要内容参考书籍为《JavaScript高级程序设计》([美]Nicholas C.Zakas)

若有纰漏,欢迎您留言指正

EventUtil对象全见

以下EventUtil对象代码亲测可用,并包含详细注释

[点击该对象中每一个方法名(绿色字体)可直接跳转到本文中介绍该方法的部分]

var EventUtil={addHandler:function(element,type,handler){ //添加事件if(element.addEventListener){ element.addEventListener(type,handler,false);  //使用DOM2级方法添加事件}else if(element.attachEvent){                    //使用IE方法添加事件element.attachEvent("on"+type,handler);}else{element["on"+type]=handler;          //使用DOM0级方法添加事件}},  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){  //使用这个方法跨浏览器取得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){  //立即停止事件在DOM中的传播//避免触发注册在document.body上面的事件处理程序if(event.stopPropagation){event.stopPropagation();}else{event.cancelBubble=true;}},getRelatedTarget:function(event){  //获取mouseover和mouseout相关元素if(event.relatedTarget){return event.relatedTarget;}else if(event.toElement){      //兼容IE8-return event.toElement;}else if(event.formElement){return event.formElement;}else{return null;}},getButton:function(event){    //获取mousedown或mouseup按下或释放的按钮是鼠标中的哪一个if(document.implementation.hasFeature("MouseEvents","2.0")){return event.button;}else{switch(event.button){   //将IE模型下的button属性映射为DOM模型下的button属性case 0:case 1:case 3:case 5:case 7:return 0;  //按下的是鼠标主按钮(一般是左键)case 2:case 6:return 2;  //按下的是中间的鼠标按钮case 4:return 1;  //鼠标次按钮(一般是右键)}}},getWheelDelta:function(event){ //获取表示鼠标滚轮滚动方向的数值if(event.wheelDelta){return event.wheelDelta;}else{return -event.detail*40;}},getCharCode:function(event){   //以跨浏览器取得相同的字符编码,需在keypress事件中使用if(typeof event.charCode=="number"){return event.charCode;}else{return event.keyCode;}}};

事实上,EventUtil是为了平衡不同浏览器间实现事件的差异或事件方法的差异而存在的

下文将详细介绍这些差异和使用EventUtil的各种方法

addHandler方法

这是EventUtil中最常用的方法,它的作用是为对象添加事件并保证兼容性

在DOM0级事件处理程序(下文均简称“DOM0级”)中

每个元素(包括windows和document)都有自己的事件处理程序属性(通常全部小写)

如常见的onload、onclick等

以Click事件为例(下同),DOM0级通常如下指定事件处理程序

var btn=document.getElementById("myBtn");
btn.onclick=function(){ //指定事件处理程序alert(this.id);      //"myBtn"
};

在DOM2级事件处理程序(下文均简称“DOM2级”)中

指定事件处理程序的方法为addEventListener( )

它接受3个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值(大多数情况下是false)

(布尔值表示是在捕获阶段(true)还是冒泡阶段(false)调用事件处理程序)

DOM2级通常如下指定事件处理程序

var btn=document.getElementById("myBtn");
//在外部定义好函数再传给addEventListener(),这样才可以通过removeEventListener()移除
var handler=function(){ alert(this.id);
};
btn.addEventListener("click",handler,false);

在旧版本IE(代表IE8-,下文均简称“IE”)中

指定事件处理程序的方法为attachEvent( )

它接受两个参数:事件处理程序名称与事件处理程序函数

IE中通常如下指定事件处理程序

var btn=document.getElementById("myBtn");
var handler=function(){alert("Clicked");
};
//注意:第一个参数是"onclick",而非DOM0的addEventListener()方法中的"click"
btn.attachEvent("onclick",handler);

由上可见,DOM0级、DOM2级和IE中指定事件方法有很大不同

EventUtil对象中的addHandler方法正是为了处理这些差异而存在

在添加了EventUtil(指上文“EventUtil对象全见”中的代码,下同)后,可以如下所示为对象指定事件处理程序

var btn=document.getElementById("myBtn");
var handler=function(){alert("Clicked!");
};
EventUtil.addHandler(btn,"click",handler);  //调用已定义的EventUtil对象

就像这样,使用addHandler方法指定事件处理程序

即可兼容支持DOM0级、DOM2级的浏览器或IE浏览器

removeHandler方法

同样的,在DOM0级、DOM2级与IE中,移除事件的方法是不同的

在DOM0级中,在不再需要某对象的事件处理程序时(如页面销毁前),可以像下面这样简单的移除事件处理程序

btn.onclick=null; 

在DOM2级中,删除事件处理程序需要使用removeEventListener( )方法,如下所示

//这里的handler应与使用addEventListener指定事件处理函数时所用的外部函数相同
btn.removeEventListener("click",handler,false);

而在IE中,删除事件则需使用detachEvent( )方法

btn.detachEvent("onclick",handler); 

因为这些差异的存在,才令EventUtil中有了removeHandler方法

在添加了EventUtil后,可以如下所示使用removeHandler方法方便地删除对象事件处理程序

//同样的,这里的handler应与使用addHandler指定事件处理函数时所用的外部函数相同
EventUtil.removeHandler(btn,"click",hanlder);

event对象与getEvent方法

你可能已经发现了,在EventUtil中,很多方法的参数都是event

这个event其实是事件对象

兼容DOM(无论是DOM0级还是DOM2级)的浏览器会将一个event对象传入到事件处理程序中

这个event对象支持许多方法,下表列出了一些常用的方法以供参考

属性/方法 类型 读/写 说明
currentTarget Element 只读 其事件处理程序当前正在处理事件的那个元素
preventDefault( ) Function 只读 取消事件的默认行为
stopPropagation( ) Function 只读 取消事件的进一步捕获或冒泡
target Element 只读 事件的实际(真正)目标
type String 只读 被触发的事件的类型

在兼容DOM的浏览器中,event对象可以如下面这个例子这样使用

var btn=document.getElementById("myBtn");
var handler=function(event){switch(event.type){      //使用event.type检测事件类型case "click":         //若是Click事件alert("Clicked");break;case: "mouseover":    //若是Mouseover事件//使用event.target获取事件目标,并更改目标样式背景颜色event.target.style.backgroundColor="red";break;case: "mouseout":     //若是Mouseout事件event.target.style.backgroundColor="";break;}
};
btn.onclick=handler;  //使用DOM0级为对象添加事件处理函数
btn.onmouseover=handler;
btn.onmouseout=handler;

需要强调的是,以上使用event事件的方法仅适用于兼容DOM的浏览器

在IE中则有所不同

在IE中,使用DOM0级添加事件处理程序时,event对象作为window对象的一个属性存在,如下例子所示

btn.onclick=function(){var event=window.event;alert(event.type);  //"click"
};

神奇的是,如果事件处理程序是使用attachEvent( )添加的,则又可以像在支持DOM的浏览器中一样

event对象又可作为参数传入事件处理程序函数中,如下例子所示

btn.attachEvent("onclick",function(event){alert(event.type); //"click"
});

而且,更神奇的是,在IE中,event对象的一些属性/方法还跟其它支持DOM的浏览器中不同,如下表

属性/方法 类型 读/写 说明
cancelBubble Boolean 读/写 默认值为false,将其设置为true就可以取消事件冒泡
(与DOM中的stopPropagation( )方法的作用相同)
returnValue Boolean 读/写 默认值为true,将其设置为false就可以取消事件的默认行为
(与DOM中的preventDefault( )方法的作用相同)
srcElement Element 只读 事件的目标(与DOM中的target属性相同)
type String 只读 被触发的事件类型

正是因为这些差异的存在,使得EventUtil中的getEvent方法应运而生

在添加了EventUtil后,可以如下“重点语句”所示获取event对象而无需担心上述差异导致的兼容问题

var btn=document.getElementById("myBtn");
var handler=function(event){event=EventUtil.getEvent(event); //重点语句
};
EventUtil.addHandler(btn,"click",handler); 

这样,就解决了event对象获取方式不同的问题

至于event对象的属性/方法差异,下文还会介绍其它方法进行处理

target对象与getTarget方法

在上一部分(“event对象与getEvent方法”)的介绍中,通过表格你可能已经发现

在IE中和其它兼容DOM的浏览器中,获取事件目标(target)的方法不同

在IE中,获取事件目标对象的方法为event.srcElement

而在其它兼容DOM的浏览器中,获取事件目标对象的方法却为event.target

getTarget方法正是为了处理这个差异而存在

在添加了EventUtil后,可以如下“重点语句”所示获取事件的目标(target)对象而无需担心上述差异导致的兼容问题

var btn=document.getElementById("myBtn");
var handler=function(event){event=EventUtil.getEvent(event); var target=EventUtil.getTarget(event); //重点语句
};
EventUtil.addHandler(btn,"click",handler); 

preventDefault方法

在其它兼容DOM的浏览器中,阻止特定事件的默认行为只需使用event对象自带的preventDefault( )方法,如下所示

var link=document.getElementById("myLink");
link.onclick=function(event){event.preventDefault(); //DOM0级或DOM2级阻止事件默认行为的方法
};

而在IE中,则需赋予event.returnValue的值为false才能阻止特定事件的默认行为

link.attachEvent("onclick",function(event){event.returnValue=false; //IE中阻止事件默认行为的方法
});

故在EventUtil中,存在一个preventDefault方法,用于统一上述差异

在添加了EventUtil后,可以如下“重点语句”所示阻止特定事件的默认行为而无需担心上述差异导致的兼容问题

var link=document.getElementById("myLink");
var handler=function(event){event=EventUtil.getEvent(event);EventUtil.preventDefault(event); //重点语句
};
EventUtil.addHandler(link,"click",handler);

stopPropagation方法

有时候,我们需要取消事件的进一步捕获或冒泡,即停止事件在DOM层次中传播

兼容DOM的浏览器可以通过使用event对象自带的stopPropagation( )方法做到这一点

var link=document.getElementById("myLink");
link.onclick=function(event){event.stopPropagation(); //DOM0级或DOM2级取消事件的进一步捕获或冒泡的方法
};

而在IE中,则需赋予event.cancelBubble的值为true

link.attachEvent("onclick",function(event){event.cancelBubble=true; //IE中取消事件的进一步冒泡的方法
});

EventUtil中的stopPropagation( )方法可以统一上述差异

在添加了EventUtil后,可以如下“重点语句”所示取消事件的进一步捕获或冒泡而无需担心差异导致的兼容问题

var link=document.getElementById("myLink");
var handler=function(event){event=EventUtil.getEvent(event);EventUtil.stopPropagation(event); //重点语句
};
EventUtil.addHandler(link,"click",handler);

“相关元素”与getRelatedTarget方法

mouseover与mouseout有“主目标(主元素)”与“相关元素”的概念

因为在发生mouseover或mouseout事件时,还会涉及到其它元素

这两个事件都会涉及把鼠指针从一个元素(相关元素)移到另一个元素(主目标)内

具体点说

对mouseover事件而言,事件的主目标是获得光标的元素,而相关元素是那个失去光标的元素

对mouseout事件而言,事件的主目标是失去光标的元素,而相关元素是那个获得光标的元素

DOM通过event对象的relatedTarget属性提供了相关元素的信息

但IE8及之前的版本不支持relatedTarget属性,不过提供了其它类似属性支持

在mouseover事件触发时,IE的formElement属性中保存了相关元素

在mouseout事件触发时,IE的toElement属性中保存了相关元素

EventUtil中的getRelatedTarget方法正是为了平衡这些差异而存在

在添加了EventUtil后,可以像下面示例“重点语句”一样使用getRelatedTarget方法

var div=document.getElementById("myDiv");
EventUtil.addHandler(div,"mouseout",function(event){event=EventUtil.getEvent(event);var target=EventUtil.getTarget(event);var relatedTarget=EventUtil.getRelatedTarget(event); //重点语句alert("鼠标离开了"+target.tagName+"元素而进入了"+relatedTarget.tagName+"元素");
});

getButton方法

我们知道,只有在鼠标主按钮被单击(或键盘回车键被按下、触摸屏被单点击中)时才会触发click事件

但对于mousedown和mouseup事件来说,鼠标上的任意按钮都可以触发它

有时,我们可能需要知道用户按下了哪个鼠标按钮

DOM的event.button属性可以做到这一点,这个属性可能有3个值

0表示主鼠标按钮(通常是左键)、1表示鼠标滚轮按钮、2表示鼠标右键

虽然IE的event对象也提供了button属性

但遗憾的是,IE的button属性与DOM的button属性有很大差异

而且不被其它浏览器支持,实用性很低,在此不予赘述

getButton方法的作用是,让所有浏览器的event.button表现与DOM相同

在添加了EventUtil后,可以像下面示例“重点语句”一样使用getButton方法而无需考虑IE中的差异

var div=document.getElementById("myDiv");
EventUtil.addHandler(div,"mousedown",function(event){ //监控按下div的是哪个按钮event=EventUtil.getEvent(event);alert(EventUtil.getButton(event));  //重点语句,弹出框显示按下哪个鼠标键的代号(0、1或2)
});
//同理,若事件是mouseup,则botton值表示释放的是哪个按钮

getWheelDelta方法

有时,为了让页面达到某些特殊效果,我们需要监视用户的鼠标滚轮操作

这一次,“与众不同”的是Firefox,而不是旧版本的IE

所有浏览器(包括IE6,除了Firefox)均支持鼠标滚轮事件mousewheel

而Firefox却是通过DOMMouseScroll事件实现类似功能

事件名的差异无法通过EventUtil改变

但关键是,这个事件表示鼠标滚轮滚动方向的方法,Firefox与其它浏览器也有差异

差异的本身已不是重点,重点是EventUtil的getWheelDelta方法可以很好的解决它们的差异

在添加了EventUtil后,可以像下面示例“重点语句”一样使用getWheelDelta方法而无需考虑FIrefox中的差异

function handleMouseWheel(event){event=EventUtil.getEvent(event);var delta=EventUtil.getWheelDelta(event);  //重点语句,delta是表示鼠标滚轮滚动方向的数值alert(delta);
}
EventUtil.addHandler(document,"mousewheel",handleMouseWheel);      //非Firefox
EventUtil.addHandler(document,"DOMMouseScroll",handleMouseWheel);  //Firefox

多数情况下,我们只需关心如上例中通过getWheelDelta方法获得的delta数值的正负

当用户向前滚动鼠标滚轮时,delta的数值为正,反之为负

滚轮滚动越多,delta数值的绝对值越大,且均是120的倍数

getCharCode方法

在所有浏览器中,按下能够插入或删除的字符的按键都会触发keypress事件

但IE8-及Opera取得字符编码(ASCII码)的方式与其它浏览器是不同的

为了解决这一差异,在EventUtil中存在getCharCode方法

在添加了EventUtil后,可以像下面示例“重点语句”一样使用getCharCode方法来获取统一的字符编码

var textbox=document.getElementById("myText");
EventUtil.addHandler(textbox,"keypress",function(event){event=EventUtil.getEvent(event);alert(EventUtil.getCharCode(event)); //重点语句,弹出窗口中显示按下按键代表字符的ASCII码
});

转载于:https://www.cnblogs.com/hykun/p/EventUtil.html

EventUtil——跨浏览器的事件对象相关推荐

  1. JavaScript --- 跨浏览器的事件对象

    var EventUtil={addHandler: function(element, type, handler){ // 添加事件方法if (element.addEventListener){ ...

  2. 原生JS实现跨浏览器的事件处理程序

    <!doctype html> <html lang="en"> <head><meta charset="UTF-8" ...

  3. addevent()实现跨浏览器绑定事件

    绑定事件一般有三种方式:传统绑定事件,IE绑定事件,W3C绑定事件.传统绑定存在可读性问题,this问题,覆盖问题.为实现跨浏览器绑定事件,我们采用自定义方法addEvent().代码如下: //跨浏 ...

  4. 一些js代码,自己备用的。高手不要笑话我。。(跨浏览器基础事件,浏览器检测,判断浏览器的名称、版本号、操作系统)...

    跨浏览器基础事件 View Code 1 //跨浏览器添加事件 2 function addEvent(obj, type, fn) { 3 if (obj.addEventListener) { 4 ...

  5. IFE-16 addEventHandler跨浏览器实现事件绑定

    /** * addEventHandler方法 * 跨浏览器实现事件绑定 */ function addEventHandler(ele, event, hanlder) {if (ele.addEv ...

  6. 跨浏览器的事件处理程序

    我们第一个要创建的方法是addHandler() 它的职责是视情况分别使用DOM0级方法.DOM2级方法或者IE方法来添加事件.这个方法属于一个名叫EventUtil的对象.addHandler() ...

  7. javascript --- DOM0级、DOM2级、跨浏览器 的事件处理程序

    DOM0级事件处理程序: // 使用DOM0级方法指定的事件处理程序被认为是元素的方法 // 这个时候的事件处理程序是在元素的作用域中运行: <div id = "myBtn" ...

  8. JavaScript --- 跨浏览器的事件处理程序

    var EventUtil = {addHandler: function(element, type, handler) { // 添加事件处理程序if (element.addEventListe ...

  9. 跨浏览器resize事件分析

    resize事件 原生事件分析 window一次resize事件: IE7 触发3次, IE8 触发2次, IE9 触发1次, IE10 触发1次 Chrome 触发1次 FF 触发2次 Opera ...

  10. dean edward大神的跨浏览器addEvent事件

    2019独角兽企业重金招聘Python工程师标准>>> function addEvent(element, type, handler) {// assign each event ...

最新文章

  1. Python 生成器总结
  2. 要毁灭人类、喷马斯克、还获得公民身份的Sophia,是假的
  3. 记一次validator jar冲突导致的启动异常
  4. Alice and Bob
  5. AWS SQS和Spring JMS集成
  6. vue 环境的搭建及初始化项目
  7. Python垃圾回收(gc)拖累了程序执行性能?
  8. 【Bootstrap】 typeahead自动补全
  9. alpine安装curl
  10. Python使用Reportlab处理PDF数据 - 其他图形
  11. matlab 矩阵 对称,如何使用Matlab产生对称矩阵 | 学步园
  12. linux网络打印机设置,linux下怎么使用网络打印机
  13. 牛顿迭代法(求平方根)
  14. 软件测试学习路线全面攻略,掌握这些技术轻松15K
  15. 周四007欧联杯 佛罗伦萨 VS 门兴[11]
  16. matlab生成的数值为inf,计算值时为Nan / inf
  17. 2022.11.12 英语背诵
  18. 制表软件带动办公软件市场新火爆
  19. Mininet教程(六):多数据中心带宽实验
  20. Power BI业绩杜邦分析

热门文章

  1. PHP报错: Can't use method return value in write context
  2. 使用CounterDownTimer实现时分秒倒计时
  3. CF891E Lust 生成函数
  4. jquery 实现图片上传,并在前端显示出来
  5. WebGIS项目中利用mysql控制点库进行千万条数据坐标转换时的分表分区优化方案...
  6. [ 原创 ]学习笔记-Android中隐式Intent 的使用
  7. 转载 关于git的常用命令总结
  8. hdu2108 判断是凸多边形还是凹多边形
  9. 将输入中的制表符替换成适当数目的空格,使空格充满到下一个制表符终止位的地方...
  10. 一些常用的前端基础操作