停止事件
我們點擊一個元素,會觸發它的默認事件,同時事件還會傳播給他的父元素。Prototype使用Event.stop()方法阻止默認事件和事件的傳播。
jQuery遵循W3C的標準,給事件提供了更多的接口:
- event.preventDefault():阻止事件目標的默認事件觸發。
- event.stopPropagation(): 阻止事件在DOM樹上傳播。
- event.stopImmediatePropagation(): 阻止當前元素的後續事件觸發,同時阻止事件在DOM樹上傳播。
我們的接口設計
我們打算給事件對象繼承下面的方法:- event.stop() – 阻止默認事件和事件傳播
- event.preventDefault() – 阻止默認事件
- event.stopPropagation() – 阻止事件傳播
實現
我創建了一個私有的函數繼承和修復事件對象,主要是修復IE的差異:function stop(event) {
event.preventDefault(event);
event.stopPropagation(event);
}
function fix(event, element) {
if (!event) var event = window.event;
event.stop = function() { stop(event); };
if (typeof event.target === 'undefined')
event.target = event.srcElement || element;
if (!event.preventDefault)
event.preventDefault = function() { event.returnValue = false; };
if (!event.stopPropagation)
event.stopPropagation = function() { event.cancelBubble = true; };
return event;
}
其他瀏覽器差異
其他的瀏覽器差異主要體現在鍵盤和鼠標事件上,jQuery處理了下面的一些差異:- Safari對文本節點處理的不同
- 某些瀏覽器對pageX/Y的不支持
- 鍵盤事件對event.which和event.metaKey的支持不同
- event.which對鼠標點擊的按鈕的序列的支持
var _isButton;
if (Prototype.Browser.IE) {
// IE doesn't map left/right/middle the same way.
var buttonMap = { 0: 1, 1: 4, 2: 2 };
_isButton = function(event, code) {
return event.button === buttonMap[code];
};
} else if (Prototype.Browser.WebKit) {
// In Safari we have to account for when the user holds down
// the "meta" key.
_isButton = function(event, code) {
switch (code) {
case 0: return event.which == 1 && !event.metaKey;
case 1: return event.which == 1 && event.metaKey;
default: return false;
}
};
} else {
_isButton = function(event, code) {
return event.which ? (event.which === code + 1) : (event.button === code);
};
}
結論
最近三篇文章我們介紹了事件的處理,我們闡述瞭如果開發一個兼容W3C和微軟的事件框架。我們瞭解了事件的生命週期,學習了怎麼阻止事件的默認事件和事件的傳播。我們同樣瞭解其他瀏覽器的差異和如何處理這些差異。我們的事件框架的代碼已經完成,你可以在github上查看:turing.events.js