关于javascript中的事件学习及总结

1关于事件对象
ie:事件对象是window对象的一个属性event
dom:event对象是作为唯一参数传递给事件处理函数。arguments[0]

2关于IE与DOM事件兼容性的总结(参考javascript高级程序设计)

DOM属性/方法IE属性/方法
altKeyaltKey
bubbles-
buttonbutton
cancelBubblecancelBubble
charCodekeyCode
clientXclientX
clientYclientY
ctrlKeyctrlKey
currentTarget-
detail-
eventPhase-
isChar-
keyCodekeyCode
metaKey-
pageXclientX+document.body.scrollLeft
pageYclientY+document.body.scrollTop
preventDefault()returnValue = false
relateTargetfromElement/toElement
screenXscreenX
screenYscreenY
shiftKeyshiftKey
stopPropagation()cancelBubble = true
targetsrcElement
timeStamp-
typetype
具体的属性和方法意思我就不写清楚了,有不太明白的可以baidu、google一下~

3关于跨平台事件(针对第二点各个属性在ie和ff下的不同)
在这里javascript高级程序设计一书总结了一个容器对象,可以方便的解决事件兼容性问题。
具体如下:
EventUtil
var EventUtil = new Object();
EventUtil.addEventHandler 
= function (oTarget, sEventType, fnHandler) {
    
if (oTarget.addEventListener) {
        oTarget.addEventListener(sEventType, fnHandler, 
false);
    } 
else if (oTarget.attachEvent) {
        oTarget.attachEvent(
"on" + sEventType, fnHandler);
    } 
else {
        oTarget[
"on" + sEventType] = fnHandler;
    }
};
        
EventUtil.removeEventHandler 
= function (oTarget, sEventType, fnHandler) {
    
if (oTarget.removeEventListener) {
        oTarget.removeEventListener(sEventType, fnHandler, 
false);
    } 
else if (oTarget.detachEvent) {
        oTarget.detachEvent(
"on" + sEventType, fnHandler);
    } 
else { 
        oTarget[
"on" + sEventType] = null;
    }
};

EventUtil.formatEvent 
= function (oEvent) {
    
if (isIE && isWin) {
        oEvent.charCode 
= (oEvent.type == "keypress"? oEvent.keyCode : 0;
        oEvent.eventPhase 
= 2;
        oEvent.isChar 
= (oEvent.charCode > 0);
        oEvent.pageX 
= oEvent.clientX + document.body.scrollLeft;
        oEvent.pageY 
= oEvent.clientY + document.body.scrollTop;
        oEvent.preventDefault 
= function () {
            
this.returnValue = false;
        };

        
if (oEvent.type == "mouseout") {
            oEvent.relatedTarget 
= oEvent.toElement;
        } 
else if (oEvent.type == "mouseover") {
            oEvent.relatedTarget 
= oEvent.fromElement;
        }

        oEvent.stopPropagation 
= function () {
            
this.cancelBubble = true;
        };

        oEvent.target 
= oEvent.srcElement;
        oEvent.time 
= (new Date).getTime();
    }
    
return oEvent;
};

EventUtil.getEvent 
= function() {
    
if (window.event) {
        
return this.formatEvent(window.event);
    } 
else {
        
return EventUtil.getEvent.caller.arguments[0];
    }
};

4里面会用到判断浏览器是什么牌子的另一个脚本(detect.js
具体代码如下:
detect.js
var sUserAgent = navigator.userAgent;
var fAppVersion = parseFloat(navigator.appVersion);

function compareVersions(sVersion1, sVersion2) {

    
var aVersion1 = sVersion1.split(".");
    
var aVersion2 = sVersion2.split(".");
    
    
if (aVersion1.length > aVersion2.length) {
        
for (var i=0; i < aVersion1.length - aVersion2.length; i++) {
            aVersion2.push(
"0");
        }
    } 
else if (aVersion1.length < aVersion2.length) {
        
for (var i=0; i < aVersion2.length - aVersion1.length; i++) {
            aVersion1.push(
"0");
        }    
    }
    
    
for (var i=0; i < aVersion1.length; i++) {
 
        
if (aVersion1[i] < aVersion2[i]) {
            
return -1;
        } 
else if (aVersion1[i] > aVersion2[i]) {
            
return 1;
        }    
    }
    
    
return 0;

}

var isOpera = sUserAgent.indexOf("Opera"> -1;
var isMinOpera4 = isMinOpera5 = isMinOpera6 = isMinOpera7 = isMinOpera7_5 = false;

if (isOpera) {
    
var fOperaVersion;
    
if(navigator.appName == "Opera") {
        fOperaVersion 
= fAppVersion;
    } 
else {
        
var reOperaVersion = new RegExp("Opera (\\d+\\.\\d+)");
        reOperaVersion.test(sUserAgent);
        fOperaVersion 
= parseFloat(RegExp["$1"]);
    }

    isMinOpera4 
= fOperaVersion >= 4;
    isMinOpera5 
= fOperaVersion >= 5;
    isMinOpera6 
= fOperaVersion >= 6;
    isMinOpera7 
= fOperaVersion >= 7;
    isMinOpera7_5 
= fOperaVersion >= 7.5;
}

var isKHTML = sUserAgent.indexOf("KHTML"> -1 
              
|| sUserAgent.indexOf("Konqueror"> -1 
              
|| sUserAgent.indexOf("AppleWebKit"> -1
              
var isMinSafari1 = isMinSafari1_2 = false;
var isMinKonq2_2 = isMinKonq3 = isMinKonq3_1 = isMinKonq3_2 = false;

if (isKHTML) {
    isSafari 
= sUserAgent.indexOf("AppleWebKit"> -1;
    isKonq 
= sUserAgent.indexOf("Konqueror"> -1;

    
if (isSafari) {
        
var reAppleWebKit = new RegExp("AppleWebKit\\/(\\d+(?:\\.\\d*)?)");
        reAppleWebKit.test(sUserAgent);
        
var fAppleWebKitVersion = parseFloat(RegExp["$1"]);

        isMinSafari1 
= fAppleWebKitVersion >= 85;
        isMinSafari1_2 
= fAppleWebKitVersion >= 124;
    } 
else if (isKonq) {

        
var reKonq = new RegExp("Konqueror\\/(\\d+(?:\\.\\d+(?:\\.\\d)?)?)");
        reKonq.test(sUserAgent);
        isMinKonq2_2 
= compareVersions(RegExp["$1"], "2.2">= 0;
        isMinKonq3 
= compareVersions(RegExp["$1"], "3.0">= 0;
        isMinKonq3_1 
= compareVersions(RegExp["$1"], "3.1">= 0;
        isMinKonq3_2 
= compareVersions(RegExp["$1"], "3.2">= 0;
    } 
    
}

var isIE = sUserAgent.indexOf("compatible"> -1 
           
&& sUserAgent.indexOf("MSIE"> -1
           
&& !isOpera;
           
var isMinIE4 = isMinIE5 = isMinIE5_5 = isMinIE6 = false;

if (isIE) {
    
var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
    reIE.test(sUserAgent);
    
var fIEVersion = parseFloat(RegExp["$1"]);

    isMinIE4 
= fIEVersion >= 4;
    isMinIE5 
= fIEVersion >= 5;
    isMinIE5_5 
= fIEVersion >= 5.5;
    isMinIE6 
= fIEVersion >= 6.0;
}

var isMoz = sUserAgent.indexOf("Gecko"> -1
            
&& !isKHTML;

var isMinMoz1 = sMinMoz1_4 = isMinMoz1_5 = false;

if (isMoz) {
    
var reMoz = new RegExp("rv:(\\d+\\.\\d+(?:\\.\\d+)?)");
    reMoz.test(sUserAgent);
    isMinMoz1 
= compareVersions(RegExp["$1"], "1.0">= 0;
    isMinMoz1_4 
= compareVersions(RegExp["$1"], "1.4">= 0;
    isMinMoz1_5 
= compareVersions(RegExp["$1"], "1.5">= 0;
}

var isNS4 = !isIE && !isOpera && !isMoz && !isKHTML 
            
&& (sUserAgent.indexOf("Mozilla"== 0
            
&& (navigator.appName == "Netscape"
            
&& (fAppVersion >= 4.0 && fAppVersion < 5.0);

var isMinNS4 = isMinNS4_5 = isMinNS4_7 = isMinNS4_8 = false;

if (isNS4) {
    isMinNS4 
= true;
    isMinNS4_5 
= fAppVersion >= 4.5;
    isMinNS4_7 
= fAppVersion >= 4.7;
    isMinNS4_8 
= fAppVersion >= 4.8;
}

var isWin = (navigator.platform == "Win32"|| (navigator.platform == "Windows");
var isMac = (navigator.platform == "Mac68K"|| (navigator.platform == "MacPPC"
            
|| (navigator.platform == "Macintosh");

var isUnix = (navigator.platform == "X11"&& !isWin && !isMac;

var isWin95 = isWin98 = isWinNT4 = isWin2K = isWinME = isWinXP = false;
var isMac68K = isMacPPC = false;
var isSunOS = isMinSunOS4 = isMinSunOS5 = isMinSunOS5_5 = false;

if (isWin) {
    isWin95 
= sUserAgent.indexOf("Win95"> -1 
              
|| sUserAgent.indexOf("Windows 95"> -1;
    isWin98 
= sUserAgent.indexOf("Win98"> -1 
              
|| sUserAgent.indexOf("Windows 98"> -1;
    isWinME 
= sUserAgent.indexOf("Win 9x 4.90"> -1 
              
|| sUserAgent.indexOf("Windows ME"> -1;
    isWin2K 
= sUserAgent.indexOf("Windows NT 5.0"> -1 
              
|| sUserAgent.indexOf("Windows 2000"> -1;
    isWinXP 
= sUserAgent.indexOf("Windows NT 5.1"> -1 
              
|| sUserAgent.indexOf("Windows XP"> -1;
    isWinNT4 
= sUserAgent.indexOf("WinNT"> -1 
              
|| sUserAgent.indexOf("Windows NT"> -1 
              
|| sUserAgent.indexOf("WinNT4.0"> -1 
              
|| sUserAgent.indexOf("Windows NT 4.0"> -1 
              
&& (!isWinME && !isWin2K && !isWinXP);


if (isMac) {
    isMac68K 
= sUserAgent.indexOf("Mac_68000"> -1 
               
|| sUserAgent.indexOf("68K"> -1;
    isMacPPC 
= sUserAgent.indexOf("Mac_PowerPC"> -1 
               
|| sUserAgent.indexOf("PPC"> -1;  
}

if (isUnix) {
    isSunOS 
= sUserAgent.indexOf("SunOS"> -1;

    
if (isSunOS) {
        
var reSunOS = new RegExp("SunOS (\\d+\\.\\d+(?:\\.\\d+)?)");
        reSunOS.test(sUserAgent);
        isMinSunOS4 
= compareVersions(RegExp["$1"], "4.0">= 0;
        isMinSunOS5 
= compareVersions(RegExp["$1"], "5.0">= 0;
        isMinSunOS5_5 
= compareVersions(RegExp["$1"], "5.5">= 0;
    }
}

4相关测试代码。

test
<html>
    
<head>
        
<title>Mouse Events Example</title>
        <script type="text/javascript" src="detect.js"></script>
        <script type="text/javascript" src="eventutil.js"></script>
        <script type="text/javascript">
   EventUtil.addEventHandler(window, 
"load"function ()
        {
            
var obj = document.getElementById("div1");
            EventUtil.addEventHandler(obj,
"click",handlee);
        
            });

   
var handlee = function()
   {
   
var obj = document.getElementById("txt1");
   
var eventobj = EventUtil.getEvent();
   obj.value 
= eventobj.target.tagName;
   obj.value 
+= "\n"+eventobj.target.id; 
     
        
   };
        
</script>
    </head>
    <body>

        
<p>Use your mouse to click and double click the red square.</p>
        <div style="width: 100px; height: 100px; background-color: red" id="div1"></div>
        <p><textarea id="txt1" rows="15" cols="50"></textarea></p>
    
</body>
</html>

5在自己测试中遇到的两个问题。
1用addEventLisenter(dom)/attachEvent(ie)时如果针对的事件触发对象是window,

事件函数必须写为声明式的像这样function foo(){}
// 错误的写法(变量式)ie会报语法错误
< script >  
window.attachEvent(
" onload " ,foo);
   
var  foo  =   function ()
   {
   alert(
" loaded " );
   };
< / script>
// 正确的写法(声明式)
< script >
window.attachEvent(
" onload " ,foo);
  
function  foo()
   {
   alert(
" loaded " );
   };
< / script>

其他的页面元素则两者皆可。

问题二:关于同一对象连续使用attachEvent执行顺序的问题
猜猜会先执行那一个alert?

< html >
< head >
< script >
    
var  app  =   function ()
    
{
        
var obj = document.getElementById("mypp");
        obj.attachEvent(
"onclick",foo1);
        obj.attachEvent(
"onclick",foo2);
    }


        
var  foo1  =   function ()
        
{
        alert(
"clicked!");
        }
;
        
var  foo2  =   function ()
        
{
        alert(
"also clicked!");
        }
;
    
< / script>
< / head>    
  < body onload = " app() " >
        
< p id = " mypp " > test < / p>
     < / body>
< / html>

答案是上面的代码会先执行第二个alert。
如果你觉得你的思维是正确的那么再看看下面的代码:

test2
<html>
<head>
<script>
var app = function()
{
var obj = document.getElementById("mypp");
obj.attachEvent(
"onclick",foo1);
obj.attachEvent(
"onclick",foo2);
obj.attachEvent(
"onclick",foo3);
obj.attachEvent(
"onclick",foo4);
obj.attachEvent(
"onclick",foo5);
obj.attachEvent(
"onclick",foo6);
obj.attachEvent(
"onclick",foo7);
}
var foo1 = function(){alert("1");};
var foo2 = function(){alert("2");};
var foo3 = function(){alert("3");};
var foo4 = function(){alert("4");};
var foo5 = function(){alert("5");};
var foo6 = function(){alert("6");};
var foo7 = function(){alert("7");};
</script>
</head> 
<body onload="app()">
<p id="mypp">test</p>
</body>
</html>

一段关于此的英文解释:
When   event   fires   on   the   object,   the   object's   event   handler   is   called   before   pDisp,   the   specified   function.   If   you   attach   multiple   functions   to   the   same   event   on   the   same   object,   the   functions   are   called   in   random   order,   immediately   after   the   object's   event   handler   is   called.
引用网上一位高人说的:
并不是什么随机问题,你可以去研究研究哈希对象,这种对象插入新元素的时候并不是顺序插入的,而是根据计算所得的hash值而定的,但在取用这些对象的时间是按照一定的顺序取的,所以就会出现你这种所谓的乱序问题。我估计DHTML里的这些对象的事件处理函数存放及JS对象都是一个个哈希对象,都是key-value这种键值对的模式。

所以在使用上还是要慎重的,最好不要做依赖于顺序的设计。


转载于:https://www.cnblogs.com/junyistar/archive/2008/04/09/1129206.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值