<!DOCTYPE HTML> <html> <head> <title></title> <style type="text/css"> #aa{ border:1px solid #000; width:100px; height:40px; margin-top:50px;} #bb{ border:1px solid #000; width:500px; height:40px; margin-top:50px;} #cc{ border:1px solid #000; width:500px; height:40px;} </style> </head> <body> <div id="aa"></div> <div id="bb">dfdfddfsd</div> <div id="cc">gregreger</div> <script type="text/javascript"> document.getElementById("aa").onclick = function (e) { if (e) alert(e.toString()); // IE6/7/8 e為undefined IE9中e為W3標准事件對象。 //e = window.event; alert(e.srcElement.tagName || e.currentTarget.tagName); } /* element.onXXX方式(比較古老,不推薦使用) 這種方式添加事件IE6/7/8只支持window.event不支持參數傳入, Firefox只支持參數傳入不支持其它方式。 IE9/Opera/Safari/Chrome 兩種方式都支持。 */ var d4 = document.getElementById('bb'); function clk(e) { alert(e); // 所有瀏覽器彈出的信息框顯示都是事件對象。 alert(e.srcElement.tagName || e.currentTarget.tagName); e = e || window.event; alert(e); // IE6/7/8中和上個e彈出相同的對象。 } if (d4.addEventListener) { d4.addEventListener('click', clk, false); alert("addEventListener"); } if (d4.attachEvent) { d4.attachEvent('onclick', clk); alert("attachEvent"); } /* addEventListener、attachEvent方式(推薦使用) 結論: 通常事件句柄里有這句話:e = e || window.event; 但是在這種調用方式(addEventListener、attachEvent方式)中沒什么作用, 這是什么原因呢?上邊參考文章的總結里指出了原因,即: “IE6/7/8支持通過window.event獲取對象, 通過attachEvent方式添加事件時也支持事件對象作為句柄第一個參數傳入” 因為IE6/7/8在attachEvent方式添加事件時同時支持兩種方式,所以事件句柄中的參數e在 IE6/7/8中會自動轉換為window.event。 這么以來,這句e = e || window.event;在此處就不需要了(個人結論)。 */ /* 在編寫跨瀏覽器的函數庫時,IE和標准事件對象的屬性的差異的問題需要解決。 下邊抽出相關代碼,討論這個問題在這里的體現。 */ var _E = { BindEvent: function (object, fun) { if (arguments.length == 1) { fun = arguments[0]; object = null; } var args = Array.prototype.slice.call(arguments, 2); return function (event) { return fun.apply(object, [fixEvent(event)].concat(args)); } } }; function fixEvent(event) { // 統一不同瀏覽器的event對象 if (event) return event; event = window.event; event.pageX = event.clientX + getScrollLeft(event.srcElement); event.pageY = event.clientY + getScrollTop(event.srcElement); event.target = event.srcElement; event.stopPropagation = stopPropagation; event.preventDefault = preventDefault; var relatedTarget = { "mouseout": event.toElement, "mouseover": event.fromElement }[event.type]; if (relatedTarget) { event.relatedTarget = relatedTarget; } return event; }; function stopPropagation() { this.cancelBubble = true; }; function preventDefault() { this.returnValue = false; }; // 測試代碼如下 function get(ev) { alert(ev.pageX); } var cc = document.getElementById("cc"); var clickHandler = _E.BindEvent(get); cc.attachEvent('onclick', clickHandler); // IE6/7/8下測試 /* 結果點擊id為cc的div元素后,彈出undefined。說明ev.pageX根本不存在。 可是我們在fixEvent()里已經做了事件對象的統一工作。 調試會發現:fixEvent()里if (event) return event;這句是執行后就直接return了, 這里的event按照道理說應該是undefined,但是事實並不是。 // 至於原因個人覺得就是這里:因為IE6/7/8在attachEvent方式添加事件時同時支持兩種方式, 所以事件句柄中的參數會自動轉換為window.event。也就是說參數不是undefined // 所以在這里用if (event) return event;判斷事件對象不妥。 (說明:fixEvent()這段代碼參考自博客園里cloudgamer的函數庫, 他里邊就是這種寫法,個人覺得有錯誤,希望有興趣的朋友也做做驗證) */ </script> </body> </html>