严格来说,有2中不同的模型:W3C模型和微软模型,除IE之外W3C模型支持所有的现代浏览器,而微软模型只支持IE,使用W3C模型的代码如下:

// 格式:target.addEventListener( type, function, useCapture );  
// 例子:
var myIntro = document.getElementById('intro');
myIntro.addEventListener('click', introClick, false);

使用IE模型的代码如下:

// 格式: target.attachEvent ( 'on' + type, function );  
// 例子:
var myIntro = document.getElementById('intro');
myIntro.attachEvent('onclick', introClick);

introClick的代码如下:

function introClick() {  
alert('You clicked the paragraph!');
}

事实上,要做出通用的话,我们可以自定义一个函数以支持跨浏览器:

function addEvent(elem, type, fn) {
if (elem.attachEvent) {
elem.attachEvent('on' + type, fn);
return;
}
if (elem.addEventListener) {
elem.addEventListener(type, fn, false);
}
}

该函数首先检查attachEvent和addEventListener属性,谁可以就用谁,这两种类型的模型都支持删除句柄功能,参考下面的removeEvent函数。

function removeEvent(elem, type, fn) {
if (elem.detachEvent) {
elem.detachEvent('on' + type, fn);
return;
}
if (elem.removeEventListener) {
elem.removeEventListener(type, fn, false);
}
}

你可以这样使用:

var myIntro = document.getElementById('intro');
addEvent(myIntro, 'click', function () {
alert('YOU CLICKED ME!!!');
});

注意到我们传入了一个匿名函数作为第三个参数,JavaScript运行我们定义和执行匿名函数,这种匿名函数特别适合作为参数传递,实际上我们也可以传递有名的函数(代码如下),但是你们函数更容易做。

如果你只想在第一次click的时候触发一个函数,你可以这么做:

// 注意:前提是我们已经定于好了addEvent/removeEvent函数
// (定义好了才能使用哦) var myIntro = document.getElementById('intro');
addEvent(myIntro, 'click', oneClickOnly); function oneClickOnly() {
alert('WOW!');
removeEvent(myIntro, 'click', oneClickOnly);
}

当第一次触发以后,我们就立即删除该句柄,但是有匿名函数的话却很难将自身的引用删除,不过实际上可以通过如下的形式来做(只不过有点麻烦):

addEvent(myIntro, 'click', function () {
alert('WOW!');
removeEvent(myIntro, 'click', arguments.callee);
});

这里我们是有了arguments对象的callee属性,arguments对象包含了所有传递进来的参数以及该函数自身(callee),这样我们就可以放心地删除自身的引用了。

Event对象

另外一个非常重要的内容是Event对象,当事件发生的时候出发某个函数,该Event对象将自动在函数内可用,该对象包含了很多事件触发时候的信 息,但IE却没有这么实现,而是自己实现的,IE浏览器是通过全局对象window下的event属性来包含这些信息,虽然不是大问题,但我们也需要注意 一下,下面的代码是兼容性的:

function myEventHandler(e) {

    // 注意参数e
// 该函数调用的时候e是event对象(W3C实现) // 兼容IE的代码
e = e || window.event; // 现在e就可以兼容各种浏览器了 } // 这里可以自由地绑定事件了

这里判断e对象(Event对象)是否存在我们使用了OR操作符:如果e不存在(为null, undefined,0等)的时候,将window.event赋值给e,否则的话继续使用e。通过这方式很快就能在多浏览器里得到真正的Event对象,如果你不喜欢这种方式的话,你可以使用if语句来处理:

if (!e) {
e = window.event;
} // 没有else语句,因为e在其它浏览器已经定义了

另外Event对象下的命令和属性都很有用,遗憾的是不不能全兼容浏览器,例如当你想取消默认的行为的时候你可以使用Event对象里的preventDefault()方法,但IE里不得不使用对象的returnValue属性值来控制,兼容代码如下:

function myEventHandler(e) {
e = e || window.event;
// 防止默认行为
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
}

例如,当你点击一个连接的时候,默认行为是导航到href里定义的地址,但有时候你想禁用这个默认行为,通过returnValue和preventDefault就可以实现,Event对象里的很多属性在浏览器里都不兼容,所以很多时候需要处理这些兼容性代码。

注意:现在很多JS类库都已经封装好了e.preventDefault代码,也就是说在IE里可用了,但是原理上依然是使用returnValue来实现的。

w3c与微软(IE)事件注册区别 -Tom的更多相关文章

  1. IE的事件与w3c事件的区别

    14. offsetWidth, scrollLeft, scrollHeight?     scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离 scrollHeig ...

  2. [JavaScript] JavaScript事件注册,事件委托,冒泡,捕获,事件流

    面试题 event 事件 事件委托是什么? 如何阻止事件冒泡,阻止默认事件呢? Javascript 的事件流模型都有什么? 事件绑定和普通事件有什么区别? Event 对象 Event 对象,当事件 ...

  3. c#之委托和事件的区别

    1.什么是委托,这里就不做介绍了,如果想了解可以查看博客:http://www.cnblogs.com/xiaoxiaogogo/p/3571494.html 下面开始对事件进行介绍 1.定义事件以及 ...

  4. C#中委托和事件的区别实例解析

    这篇文章主要介绍了C#中委托和事件的区别,并分别以实例形式展示了通过委托执行方法与通过事件执行方法,以及相关的执行流程与原理分析,需要的朋友可以参考下 本文实例分析了C#中委托和事件的区别,分享给大家 ...

  5. C#中委托和事件的区别

    大致来说,委托是一个类,该类内部维护着一个字段,指向一个方法.事件可以被看作一个委托类型的变量,通过事件注册.取消多个委托或方法.本篇分别通过委托和事件执行多个方法,从中体会两者的区别. □ 通过委托 ...

  6. 委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别

    在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式,并从中体验委托与事件 ...

  7. c# 委托与事件的区别

    委托与事件的区别 委托和事件没有可比性,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装.),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别.事件的内部 ...

  8. jquery的bind跟on绑定事件的区别

    jquery的bind跟on绑定事件的区别:主要是事件冒泡: jquery文档中bind和on函数绑定事件的用法: .bind(events [,eventData], handler) .on(ev ...

  9. libevent (三) 事件注册与循环监听

    事件注册与循环监听 在libevent中为了监听某种事件的发生,设置事件触发后的回调函数,也就是说对该事件注册到当前的IO模型中. 事件注册 事件初始化 使用`event_new`函数来对事件进行初始 ...

随机推荐

  1. mysqlbinlog抽取二进制日志中某库某表的日志

    1.先使用myqlbinlog命令把整个库的二进制日志抽取出来 mysqlbinlog --database=db_name mysql-bin.xxxxxx > db_name.sql 2.然 ...

  2. [Ogre][地形]OgreTerrain分析以及使用

    Ogre 1.7.2中的地形教程 ○读者可以对照着Ogre1.7.2中的terrain.h源码进行阅读加深理解,蓝色部分均为源码 ○去除了一些具体场景比如添加mesh,设置setAmbientLigh ...

  3. DBUtils开源JDBC类库,对JDBC简单封装(作用是:简化编码工作量,同时不会影响程序的性能)

    DBUtils:提高了程序的性能,编程更加简便 架包 mysql-connector-java-jar commons-dbcp-1.4jar commons-pool-1.5.5jar common ...

  4. 在Windows Live Writer中插入C# code

    平时都是用Windows Live Writer写博客,发布博客.遇到需要插入代码都是先在notepad中写好,或者是拷贝到notepad,再从notepad中拷到Windows Live Write ...

  5. TreeView 节点的显示,读取,操作

    using System;using System.Collections;using System.Configuration;using System.Data;using System.Linq ...

  6. java中的动态代理机制

    java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...

  7. ioshittest的用法

    昨天,发一个一个BUG.应用了一个第三方控件.一切好,效果出来符合要求. 准备收工时,再次进行测试,发现一个很严重后果的BUG,view上的按钮事件都没了. 经过各种测试,发现就是新引入的第三方控件引 ...

  8. CentOS6.5下安装wine OK

    这篇文章主要记录了如何在CentOS 6.5上安装Wine 1.7.24开发版 1.安装需要的软件包 # yum groupinstall ‘Development Tools‘ # yum inst ...

  9. shell 中的>文件重定向符 和 标准输入、输出、错误以及 2&1 的含义*

    http://www.cnblogs.com/chenmh/p/5382044.html 问:其中 的2>&1是怎么回事? . test.sh > test.log 2>&a ...

  10. 01scala环境搭建和基础

    1.环境搭建 1.下载安装jdk1.7以上版本,并进行环境变量的配置 2.下载scala-2.10.4.msi,安装后进行环境变量的配置 3.下载scala-SDK-4.1.1-vfinal-2.11 ...