传统与DOM2级事件绑定的区别:
1.传统事件绑定同一事件句柄只能绑定一个事件函数,绑定多个后面的会覆盖前面的;DOM2级支持同一元素的同一事件句柄可以绑定多个监听函数;
传统:window.onnload=function(){
alert("a");
}
window.onnload=function(){
alert("b");
}
打印 b//跨浏览器事件绑定
function addEvent(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;
}
}
addEvent(window,"load",function(){
alert("1");
});
addEvent(window,"load",function(){
alert("2");
});
打印:1 2 IE打印:2,1
DOM2级与IE区别:
1.同一事件句柄绑定的多个监听函数,DOM2级按正序触发,IE按反序触发,例子如上
2.如果在同一元素的同一事件句柄上多次注册同一函数,DOM2第一次注册后的所有注册都被忽略;IE不会忽略
window.οnlοad=function(){var oBtn=document.getElementById("button");
addEvent(oBtn,"click",fn);
addEvent(oBtn,"click",fn);
addEvent(oBtn,"click",fn);
}
function fn(){
alert("button");
}
打印一次button,IE打印三次
3.在函数体内不必用使用event = event || window.event; 来标准化Event 对象;IE的attach中本身就传递了event
window.οnlοad=function(){
var oBtn=document.getElementById("button");
addEvent(oBtn,"click",fn);
}
function fn(e){
alert(e.clientX); //e 不必做兼容
}
3.this传递:attach方法事件处理程序会在全局作用域下运行,IE的this传递传递代表的是window
解决方法:对象冒充
function addEvent(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent("on"+type,function(){ //加个匿名函数
handler.call(element); //对象冒充
});
}else{
element["on"+type]=handler;
}
}
function fn(){
//alert(e.clientX); //事件不必做兼容
alert(this.value);
}
handler.call(element,123,445); //默认第一个参数传给this,后面的可以通过形式参数来获取
function fn(a,b){
//alert(e.clientX); //事件不必做兼容
alert(a); //123
alert(b); //456
alert(this.value);
}
使用了call 传递this,带来的诸多另外的问题:1.无法标准化event;2.无法删除事件。
导致的原因很明确,就是使用了匿名函数。标准化event 可以解决,无法删除事件就没有办
法了,因为无法确定是哪一个事件。
obj.attachEvent('on' + type, function () {
fn.call(obj, window.event);
});
function fn(e){
alert(e.clientX); //事件不必做兼容
}