1. 程式人生 > >Jquery封裝之----事件繫結(一)

Jquery封裝之----事件繫結(一)

在今天的部落格中,有些問題比較突出,所以要多多注意
一.問題所在
現代繫結中W3C 使用的是:addEventListener 和removeEventListener。IE 使用的是
attachEvent 和detachEvent。我們知道IE 的這兩個問題多多,並且伴隨記憶體洩漏。所以,解
決這些問題非常有必要。
那麼我們希望解決非IE 瀏覽器事件繫結哪些問題呢?
1.支援同一元素的同一事件控制代碼可以繫結多個監聽函式;
2.如果在同一元素的同一事件控制代碼上多次註冊同一函式,那麼第一次註冊後的所有註冊
都被忽略;
3.函式體內的this 指向的應當是正在處理事件的節點(如當前正在執行事件控制代碼的節
點);
4.監聽函式的執行順序應當是按照繫結的順序執行;
5.在函式體內不用使用event = event || window.event; 來標準化Event 物件;
二.設定程式碼
//跨瀏覽器新增事件
function addEvent(obj, type, fn) {
if (typeof addEventListener != 'undefined') {
obj.addEventListener(type, fn, false);
} else if (typeof attachEvent != 'undefined') {
obj.attachEvent('on' + type, fn);
}
}
//跨瀏覽器刪除事件
function removeEvent(obj, type, fn) {
if (typeof removeEventListener != 'undefined') {
obj.removeEventListener(type, fn);
} else if (typeof detachEvent != 'undefined') {
obj.detachEvent('on' + type, fn);
}
}
上面的這兩個函式解決了:1.同時繫結多個函式;2.標準event;
上面的這兩個函式沒有解決的問題:1.IE 多次註冊同一函式未被忽略;2.IE 中順序是倒
序;3.IE 中this 傳遞過來的是window
/*
這裡需要特別注意的是,經過我的測試,IE傳過來的並不是window,傳過來的依然是點選按鈕的值
*/
為了解決this 傳遞問題,我們需要使用匿名函式+傳遞方式引數的方式來解決:
obj.attachEvent('on' + type, function () {
fn(obj);
});
addEvent(oButton, 'click', function (_this) {
alert(_this.value);
});
這種方式比較古板,更好一點的方式是使用call 來冒充物件。
obj.attachEvent('on' + type, function () {
fn.call(obj);
});
addEvent(oButton, 'click', function () {
alert(this.value);
});
call 的用法回憶一下:
fn.call(obj); //this 就是obj 物件
fn.call(123); //this 就是123
fn.call(123,456); //this 就是123,第一個引數是456
PS:也就是說,使用了call 第一個引數就是this 獲取,從第2 個引數開始,可以通過函
數引數獲取,以此類推。
使用了call 傳遞this,帶來的諸多另外的問題:1.無法標準化event;2.無法刪除事件。
導致的原因很明確,就是使用了匿名函式。標準化event 可以解決,無法刪除事件就沒有辦
法了,因為無法確定是哪一個事件。
obj.attachEvent('on' + type, function () {
fn.call(obj, window.event);
});
在這裡我還要宣告一下,不知道是不是我是window10的問題,在上述的1,2點,在我的電腦上是沒有問題的,在我的電腦上
1.支援同一元素的同一事件控制代碼可以繫結多個監聽函式;
2.如果在同一元素的同一事件控制代碼上多次註冊同一函式,那麼第一次註冊後的所有註冊
都被忽略;
這幾點經過測試,並不需要做什麼改變,所以後面的幾點也就沒有什麼變化了,個人覺得有點畫蛇添足了。