w3c与微软(IE)事件注册区别 -Tom

严格来说,有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来实现的。

原文地址:https://www.cnblogs.com/weilantiankong/p/4538839.html