e = e || window.event的區別及用法。
e = e || window.event 在做事件處理時,用於區分IE和其他瀏覽器事件物件。
下面連結為事件物件的參考資料:
http://wenku.baidu.com/view/400a89f4f61fb7360b4c65ca.html
<!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">
/*JS的event.srcElement與event.target(觸發事件物件)
IE下,event物件有srcElement屬性,但是沒有target屬性;
Firefox下,event物件有target屬性,但是沒有srcElement屬性.但他們的作用是相當的,即:
firefox 下的 event.target = IE 下的 event.srcElement
解決方法:使用obj = event.srcElement ? event.srcElement : event.target;
或:var evtTarget = event.target || event.srcElement;
*/
//event.srcElement:表示的當前的這個事件源。
//
//event.srcElement.parentNode:表示當前事件源的父節點。
//
// parentNode:父節點,也就是上一層的節點。可以是任何一個標籤。
//
//event.srcElement.firstChild:當前事件的第一個節點,如果節點是input,通過event.srcElement.firstChild.value就可以獲取此input的值。
//
//event.srcElement.parentElement:是指在滑鼠所在物件的上一個物件。
//
//event.srcElement.children:當前節點下物件的個數,有多個的話就是個陣列,如當前節點下有2個input的物件,要獲取這兩個可以用event.srcElement.children[0] 與 event.srcElement.children[1]分別獲取。
//
document.getElementById("aa").onclick = function(e) {
if(e) console.log(e.toString()); // IE6/7/8 e為undefined IE9中e為W3標準事件物件。
//e = window.event;
console.log(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彈出相同的物件。
};
//addEventListener() 用於向指定元素新增事件。
// 引數說明:tr件,比如 click mouseenter mouseleave
//fn 回撥函式
//useCaption 用於描述是冒泡還是捕獲。預設值是false,即冒泡傳遞。
//當值為true,就是捕獲傳遞。
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>