1關(guān)于事件對(duì)象
ie:事件對(duì)象是window對(duì)象的一個(gè)屬性event
dom:event對(duì)象是作為唯一參數(shù)傳遞給事件處理函數(shù)。arguments[0]
2關(guān)于IE與DOM事件兼容性的總結(jié)(參考javascript高級(jí)程序設(shè)計(jì))
DOM屬性/方法 |
IE屬性/方法 |
altKey |
altKey |
bubbles |
- |
button |
button |
cancelBubble |
cancelBubble |
charCode |
keyCode |
clientX |
clientX |
clientY |
clientY |
ctrlKey |
ctrlKey |
currentTarget |
- |
detail |
- |
eventPhase |
- |
isChar |
- |
keyCode |
keyCode |
metaKey |
- |
pageX |
clientX+document.body.scrollLeft |
pageY |
clientY+document.body.scrollTop |
preventDefault() |
returnValue = false |
relateTarget |
fromElement/toElement |
screenX |
screenX |
screenY |
screenY |
shiftKey |
shiftKey |
stopPropagation() |
cancelBubble = true |
target |
srcElement |
timeStamp |
- |
type |
type |
具體的屬性和方法意思我就不寫清楚了,有不太明白的可以baidu、google一下~
3關(guān)于跨平臺(tái)事件(針對(duì)第二點(diǎn)各個(gè)屬性在ie和ff下的不同)
在這里javascript高級(jí)程序設(shè)計(jì)一書總結(jié)了一個(gè)容器對(duì)象,可以方便的解決事件兼容性問題。
具體如下:

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里面會(huì)用到判斷瀏覽器是什么牌子的另一個(gè)腳本(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相關(guān)測(cè)試代碼。

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在自己測(cè)試中遇到的兩個(gè)問題。
1用addEventLisenter(dom)/attachEvent(ie)時(shí)如果針對(duì)的事件觸發(fā)對(duì)象是window,
事件函數(shù)必須寫為聲明式的像這樣function foo(){}
//錯(cuò)誤的寫法(變量式)ie會(huì)報(bào)語法錯(cuò)誤
<script>
window.attachEvent("onload",foo);
var foo = function()
{
alert("loaded");
};
</script>
//正確的寫法(聲明式)
<script>
window.attachEvent("onload",foo);
function foo()
{
alert("loaded");
};
</script>
其他的頁面元素則兩者皆可。
問題二:關(guān)于同一對(duì)象連續(xù)使用attachEvent執(zhí)行順序的問題
猜猜會(huì)先執(zhí)行那一個(gè)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>
答案是上面的代碼會(huì)先執(zhí)行第二個(gè)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>
一段關(guān)于此的英文解釋:
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.
引用網(wǎng)上一位高人說的:
并不是什么隨機(jī)問題,你可以去研究研究哈希對(duì)象,這種對(duì)象插入新元素的時(shí)候并不是順序插入的,而是根據(jù)計(jì)算所得的hash值而定的,但在取用這些對(duì)象的時(shí)間是按照一定的順序取的,所以就會(huì)出現(xiàn)你這種所謂的亂序問題。我估計(jì)DHTML里的這些對(duì)象的事件處理函數(shù)存放及JS對(duì)象都是一個(gè)個(gè)哈希對(duì)象,都是key-value這種鍵值對(duì)的模式。
所以在使用上還是要慎重的,最好不要做依賴于順序的設(shè)計(jì)。
Tag標(biāo)簽: javascript,事件,event