關于addEvent的思考

新博客地址:http://gengliming.com

把昨天看的關于addEvent的文章總結(jié)一下

分析一下傳統(tǒng)addEvent的實現(xiàn):

// 傳統(tǒng)寫法大致上是這樣
// 作者:Scott Andrew
function addEvent(obj, type, fn, useCapture) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, useCapture);
    return true
  } else if (obj.attachEvent) {
    var r = obj.attachEvent("on"+type, fn);
    return r;
  } else {
    alert("事件處理器不能附加");
  }
}
優(yōu)勢:

1、沒有限制的程序處理,可以添加任意多個;
2、避免ie的內(nèi)存問題:有一個中央函數(shù)來來設置事件處理程序,這種方法允許你對所有的事件處理程序保存在數(shù)組或?qū)ο笾?,這樣在unload方法中就可以移除事件處理器與dom元素的綁定。

當然也是有問題的:

1、addEventListener和attachEvent的區(qū)別:猛戳這里-The this keyword;
2、類似foldout菜單,每個li中有個a標簽,當mouseover和mouseout的時候修改li的class。那我在handler中怎么拿到li呢?既然this在The this keyword提到是有問題的,那用event.target來獲取li從而修改class呢?很可惜,li被a蓋住了,所以target獲取到的是a。

看看專家Dean.Edwards是如何實現(xiàn)的:

// 作者:Dean.Edwards
function addEvent(element, type, handler) {
  // 為每個handler賦值一個唯一的ID
  if (!handler.$$guid) handler.$$guid = addEvent.guid++;
  // 為element創(chuàng)建一個事件類型的hash表
  if (!element.events) element.events = {};
  // 為每個element/event對兒創(chuàng)建一個事件handler的hash表
  var handlers = element.events[type];
  if (!handlers) {
    handlers = element.events[type] = {};
    // 保存已有的事件處理程序(如果有一個的話)
    if (element["on" + type]) {
      handlers[0] = element["on" + type];
    }
  }
  // 把handler保存在hash表
  handlers[handler.$$guid] = handler;
  // 賦值一個全局事件處理程序來做所有的工作
  element["on" + type] = handleEvent;
}; // 這里為何加分號

// 用來創(chuàng)建唯一ID的計數(shù)器
addEvent.guid = 1;

function removeEvent(element, type, handler) {
  // 從hash表刪除事件處理程序
  if (element.events && element.events[type]) {
    delete element.events[type][handler.$$guid];
  }
}; // 這里為何加分號

function handleEvent(event) {
  // 拿到event對象(ie是全局event對象)
  event = event || window.event;
  // 得到事件處理程序的hash表的引用
  var handlers = this.events[event.type];
  // 執(zhí)行每個時間處理器
  for (var i in handlers) {
    this.$$handleEvent = handler[i];
    this.$$handleEvent(event);
  }
}

這樣的好處是什么呢?

  • 1、沒有對象檢測;
  • 2、沒有使用addeventListener/attachEvent;
  • 3、保證了正確的作用域(指this關鍵字);
  • 4、正確的傳遞了event對象;
  • 5、完全的跨瀏覽器(ie4或ns4可能也能正常使用);
  • 6、 并且讓我說的話,它是沒有內(nèi)存泄漏的。

參考

addEvent() – My Solution:js專家的addEvent是這么寫的;
The this keyword:this關鍵字在事件中的不同表現(xiàn);
addEvent() considered harmful:通用的addEvent居然有這么多問題。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • JavaScript 程序采用了異步事件驅(qū)動編程模型。在這種程序設計風格下,當文檔、瀏覽器、元素或與之相關的對象發(fā)...
    劼哥stone閱讀 1,335評論 3 11
  • 前言:之前的上傳圖片用到了event.target,但是后來仔細思考了一下,自己對event.target,thi...
    Ruby君閱讀 2,142評論 1 3
  • 事件流: 事件流:頁面接收事件的順序。 IE定義的:事件冒泡流(由最具體的元素依次傳播到DOM樹的最上層的Docu...
    xiaoguo16閱讀 664評論 0 0
  • 1.JQuery 基礎 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設計者無需花費時間糾纏JS復雜的高級特性。 1....
    LaBaby_閱讀 1,277評論 0 1
  • 隆詩大婚的事兒恐怕是開年之出最沸騰的話題。 早在大婚前,四爺便闊氣地說,自己平時一向節(jié)儉,但婚禮預算無上限。 一諾...
    顆粒crown閱讀 912評論 0 3

友情鏈接更多精彩內(nèi)容