DOM2级事件绑定兼容性问题完美解决方案(attachEvent兼容性问题解决)

作者:日期:2012-12-25 11:17:29 点击:239

用DOM2级的事件绑定方法(即jQuery里bind和unbind方法的实现过程)

      珠峰培训课堂示例

解决了以下三个兼容性问题(主要是IE下attachEvent兼容性问题解决)

1、能兼容各主流浏览器

2、IE里this关键字指向window(现在IE里this会表示被绑定的这个元素)

3、IE里事件触发的顺序和标准浏览器相反(现在一致了);

这个方法和jQuery里的bind、unbind方法一样的效果

 


以下部分是测试代码,其中的bind是绑定事件的方法,unbind方法是解除事件绑定的方法

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>珠峰培训-DOM2级事件绑定完美解决</title>
<style type="text/css">
div{ width:400px; height:200px; background:red;}
</style>
</head>
 
<body>
<div id="div1" ></div>
</body>
</html>
<script type="text/ecmascript">
//珠峰培训课堂示例
var oDiv=document.getElementById('div1');
//oDiv.addEventListener('click',function(){alert(this.id)},false);
 
function IEbind(ele,sType,fn){ //
//为了结构清析,把IE里的绑定处理独立成一个方法
if(!ele['attr'+sType]){
ele['attr'+sType]=[];
}
var fnTemp=
(function(fn,ele){
//使原来方法绑定之后,this关键字能够指向ele
//相当于穿了马甲的方法
return function(event){fn.call(ele,event)}
})(fn,ele);
fnTemp.photo=fn;//使原来的方法和现在穿了马甲的方法发生关联
ele['attr'+sType].push(fnTemp);
ele.attachEvent('on'+sType,fnTemp);
}
function bind(ele,sType,fn){
if(ele.addEventListener){
ele.addEventListener(sType,fn,false);
}else if(ele.attachEvent){
if(!ele['sequence'+sType]){//这个数组是负责按顺序存诸,就是按绑定的顺序把方法存在这个数组里,
ele['sequence'+sType]=[];//如果它不存在,就自定义一个这样的数组
}
ele['sequence'+sType].push(fn);
//W3C先绑定的先运行
//先绑定的后运行 (倒序)
//没有事件被绑定的情况下(ele['attr'+sType]不存在或它的length为0的时候)不需把顺序重新组织
//没有方法被绑定
if((!ele['attr'+sType])||ele['attr'+sType].length==0)
IEbind(ele,sType,fn);
else{
while(ele['attr'+sType].length){
//把原来绑定的都移除,然后再把顺序颠倒过来重新绑定
unbind(ele,sType,ele['attr'+sType][0].photo);
//ele['attr'+sType].splice(0,1);
}
for(var i=ele['sequence'+sType].length-1;i>=0;i--){
//然后再把顺序颠倒过来重新绑定
IEbind(ele,sType,ele['sequence'+sType][i]);
}
}
//被绑定元素上的函数里的this关键字都会指向window
}else{
//ele['on'+sType]=fn;
//不需要考虑
}
}
function unbind(ele,sType,fn){
if(ele.removeEventListener){
ele.removeEventListener(sType,fn,false);
}else if(ele.detachEvent){
if(ele['attr'+sType]){
for(var i=0;i<ele['attr'+sType].length;){
var fnTemp=ele['attr'+sType][i]
if(fnTemp.photo==fn){
ele.detachEvent('on'+sType,fnTemp);
ele['attr'+sType].splice(i,1);
//如果删掉了,则不需要i++
}else{
i++ ;//删不掉,再i++
}
}
}
}
}
var n=0
function fn(){alert(this.id)}
function fn1(){alert('fn1');}
function fn2(){alert('fn2');}
function fn3(){alert(++n);
if(n==3){
unbind(oDiv,'click',fn2)
}
if(n==4){
unbind(oDiv,'click',fn1)
}
if(n==5){
unbind(oDiv,'click',fn)
}
 
}
bind(oDiv,'click',fn);
bind(oDiv,'click',fn1);
bind(oDiv,'click',fn2);
bind(oDiv,'click',fn3);
</script>
 

上一篇: javaScript照片墙-图片拖拽完美版-js桌面应用效果

下一篇: jQuery里的offset方法是怎么实现的(获得网页元素到浏览器左上角的绝对位置)