根据 W3C DOM 2 Events 描述,EventTarget 接口被所有支持 DOM 事件模型的节点(Node)实现。 该接口提供了 'addEventListener' 和 'removeEventListener' 方法,用来绑定或解绑一个 EventListeners 接口到一个 EventTarget。

DOM 2 Events 中定义了 Event 接口,用来提供事件的上下文信息,它提供了若干标准属性和方法。 实现 Event 接口的对象一般作为第一个参数传入事件处理函数,以用来提供当前事件相关的一些信息。

事件注册

根据 DOM 2 Events 中描述,节点使用 'addEventListener' 和 'removeEventListener' 方法绑定和解绑事件监听器,但 IE6 IE7 IE8 不支持这两个方法, 而使用 'attachEvent' 和 'detachEvent' 方法作为替代方案,Opera 两类方法都支持。Chrome Safari Firefox 只支持标准方法。

为了解决浏览器兼容问题,可以自定义函数来解决。例如:

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;        }    }};

关于 'addEventListener' 和 'attachEvent' 有几点需要注意:

  • IE 不支持在捕获阶段触发事件监听器,'attachEvent' 方法没有提供参数说明是否响应在捕获阶段触发的事件;
  • 'addEventListener' 和 'attachEvent' 都可以注册多个事件监听器;
  • 在 Firefox Chrome Safari Opera 中给同一事件注册同一个事件监听器多次,重复注册的会被丢弃;而在 IE 中重复注册的事件监听器会被重复执行多次;
  • 当给同一元素注册了多个事件监听器的时候,IE6 IE7 的事件监听器执行顺序是随机的,IE8 是倒序的,Firefox Chrome Safari Opera 是顺序的;
  • 当元素注册的事件监听器中有非法的事件监听器时(非函数),在 IE Firefox 中会抛出异常,而在 Chrome Safari Opera 中则会忽略非法的事件监听器,继续执行其他的事件监听器。

事件对象

在ie中,事件对象是作为一个全局变量来保存和维护的。 所有的浏览器事件,不管是用户触发的,还是其他事件, 都会更新window.event 对象。 所以在代码中,只要轻松调用 window.event 就可以轻松获取 事件对象, 再 event.srcElement 就可以取得触发事件的元素进行进一步处理。

对于标准的 DOM 处理来说, 事件对象却不是全局对象,一般情况下,是现场发生,现场使用,把事件对象自动传递给对应的事件处理函数。 在代码中,函数的第一个参数就是事件对象了。

为了解决兼容性问题,通常在代码中如下处理:

function handler(e){  e = e || window.event;}

需要注意的是,使用 <button id="btn" onclick="foo()">按钮1</button> 进行事件注册,标准方式下却不能在事件处理方法中取得事件对象。

原因是 οnclick="foo()"   就是直接执行了, foo() 函数,没有任何参数传递给 foo 函数。

有两个办法解决这个问题。

第一,将注册的方法修改为 <button id="btn" onclick="foo(event)">按钮</button>,注意,这里的 event 不是形参,而是实参,必须名为 event。这样 foo 函数就可以得到事件参数了。

第二,不修改注册的代码,在事件处理方法上进行处理。关键在于此时实际上存在事件对象,只不过没有传递给 foo 函数罢了,我们可以找到调用 foo 函数的那个函数,当然这是一个系统函数,没有关系,通过 foo.caller 可以取得当前调用 foo 函数的函数,这个函数的第一个参数就是事件对象,所以,我们可以这样取得这个事件对象了。foo.caller.arguments[0]

注意:

  • 只有在使用 attachEvent 方法注册事件监听器的时候,IE 才支持使用事件监听器传入的第一个参数作为事件对象的方式;
  • Chrome Safari Opera 两种获取事件对象的方式都支持;
  • Firefox 只支持获取事件对象的标准方式。

事件对象的属性

IE 对事件对象的标准属性和方法支持有限,针对大部分属性和方法,IE 都提供了一套替代非标准的替代方案; 而 Firefox Chrome Safari Opera 除了全面支持事件对象的标准属性和方法外,还在不同程度上支持了 IE 提供的非标准替代方案。

使用特性判断使用与标准对应的非标准方法及属性

  target          srcElement

  preventDefault()     returnValue

  stopPropagation()    cancelBubble

  relatedTarget      fromElement toElement

例如:

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;    }}

参考资料:

SD9011: 事件模型在各浏览器中存在差异

DOM 中的事件处理相关推荐

  1. 【转】理解JavaScript中的事件处理

    这篇文章对于了解Javascript的事件处理机制非常好,将它全文转载于此,以备不时之需. 转载地址:http://www.cnblogs.com/binyong/articles/1750263.h ...

  2. 如何处理JavaScript中的事件处理(示例和全部)

    In this blog, I will try to make clear the fundamentals of the event handling mechanism in JavaScrip ...

  3. php js怎么去掉类属性,如何修改DOM中的属性,类和样式

    通过jQuery来获取要修改的DOM元素,然后通过JavaScript中方法来对属性.类以及样式进行修改 今天在本篇文章中将分享的是如何通过修改html元素节点的样式,类和属性来进一步的更改dom,, ...

  4. HTML中常见的各种位置距离以及dom中的坐标讨论

    最近在学习JavaScript,特意买了一本犀牛角书来看看,尼玛一千多页,看的我头昏脑涨,翻到DOM这章节,突然记起平常在使用DOM时,碰到了好多的这个dom里面的各种宽度,高度,特意在此写一写,写的 ...

  5. DOM中Event 对象如何使用

    DOM中Event 对象如何使用 一.总结 一句话总结: 1.将event作为参数传递进来,然后就可以调用event对象的各种属性和方法了. <body onmousedown="wh ...

  6. Android菜鸟的成长笔记(11)——Android中的事件处理

    原文: [置顶] Android菜鸟的成长笔记(11)--Android中的事件处理 Android提供了两种方式来处理事件,一个是基于回调的事件处理,另一个是基于监听的事件处理,举个例子: 基于回调 ...

  7. html5中的dom中的各种节点的层次关系是怎样的

    html5中的dom中的各种节点的层次关系是怎样的 一.总结 一句话总结:Node节点是所有节点的基类,所以都继承它的方法 1.dom提供在js中动态修改html标签的作用 比如增加修改标签等,并且是 ...

  8. DOM中严格区分大小写

    DOM中严格区分大小写.例如吧input.onblur写为input.onBlur则不会执行后面的代码

  9. DOM中的navigate()函数

    DOM中的navigate()函数只在IE浏览器中有效果,在火狐中无效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transition ...

最新文章

  1. 如何跟机器人“抢”工作?专家:新的分工将形成
  2. 六大策略迎接数据中心巨大变革
  3. Nodejs获取MySQL数据_nodejs同步调用获取mysql数据时遇到的大坑
  4. adobe Director的一些快捷键(direct_Shortcut)
  5. CamShift算法,OpenCV实现(3):CamShift算法
  6. 在PB中使用WINSOCK.OCX做双向通信的简单例子
  7. 【语音识别】基于matlab GUI HMM中文语音识别【含Matlab源码 1385期】
  8. TP-LINK WR703N 变砖救活
  9. mysql codesmith_CodeSmith连接不上MySQL的解决方法
  10. windows10桌面壁纸的储存地址在哪里
  11. 自研返利网源码、有需要的私信
  12. mtk 6577 root
  13. 微信公众号开发模式开启总结
  14. 设置App标题栏与手机状态栏背景颜色一致
  15. 深度学习之LSTM案例分析(二)
  16. 太壹币——中国互金区块链组长李礼辉:发达国家对虚拟货币态度正在转变
  17. Android调用系统相机拍摄视频以及获取缩略图
  18. 已解决,软件V2报错 failed to read response header > websocket: close 1005 (no status)问题
  19. 东莞爱维EVER总线步进电机驱动器profinet连接实例
  20. 华师大 OJ 3023

热门文章

  1. Oracle 有long类型字段的表 使用insert into select 语句 ,出现:ORA-00997 错误
  2. gradle 编译失败,出现 permgen space的问题
  3. cocos2dx视频教程进阶篇--第2天--打砖块游戏-box2d物理引擎
  4. CoreAnimation-Layer详解
  5. AppWidget实现机制分析--launcher添加和删除appwidget深入分析
  6. 原生 js 轮播图(8)
  7. 《HTML5游戏编程核心技术与实战》——2.5 绘制文字
  8. android studio中添加新的model时候
  9. iOS UIWebView打电话
  10. Git(二):Git的安装配置与基本使用