發(fā)文章
發(fā)文工具
撰寫
網文摘手
文檔
視頻
思維導圖
隨筆
相冊
原創(chuàng)同步助手
其他工具
圖片轉文字
文件清理
AI助手
留言交流
寫Event處理的庫函數(shù)一個難點就在于瀏覽器兼容性問題,在IE低版本瀏覽器中事件對象始終在window.event屬性中,而在其它瀏覽器中event會作為事件處理程序中作為第一個參數(shù)傳入。而且其Event對象的屬性和方法也有諸多差異,在JavaScript與HTML交互——事件中基本有所總結,不過還是抄一段關于事件處理程序綁定方面的差異
1. 參數(shù)個數(shù)不相同,這個最直觀,addEventListener有三個參數(shù),attachEvent只有兩個,attachEvent添加的事件處理程序只能發(fā)生在冒泡階段,addEventListener第三個參數(shù)可以決定添加的事件處理程序是在捕獲階段還是冒泡階段處理(我們一般為了瀏覽器兼容性都設置為冒泡階段)
2. 第一個參數(shù)意義不同,addEventListener第一個參數(shù)是事件類型(比如click,load),而attachEvent第一個參數(shù)指明的是事件處理函數(shù)名稱(onclick,onload)
3. 事件處理程序的作用域不相同,addEventListener得作用域是元素本身,this是指的觸發(fā)元素,而attachEvent事件處理程序會在全局變量內運行,this是window,所以剛才例子才會返回undefined,而不是元素id
4. 為一個事件添加多個事件處理程序時,執(zhí)行順序不同,addEventListener添加會按照添加順序執(zhí)行,而attachEvent添加多個事件處理程序時順序無規(guī)律(添加的方法少的時候大多是按添加順序的反順序執(zhí)行的,但是添加的多了就無規(guī)律了),所以添加多個的時候,不依賴執(zhí)行順序的還好,若是依賴于函數(shù)執(zhí)行順序,最好自己處理,不要指望瀏覽器
先寫四個最簡單的
(function (window) { var ssLib = { getEvent: function (e) { return e ? e : window.event; }, getTarget: function (e) { var e = this.getEvent(e); return e.target || e.srcElement; }, preventDefault: function (e) { var e = this.getEvent(e); if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; } }, stopPropagation: function (e) { var e = this.getEvent(e); if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; } } }; window.ssLib = window.ss = ssLib; })(window);
代碼很簡單,相信聰明的小伙兒伴們一看就懂,就不多做解釋了
addEvent: function (element, type, handler, key) { var key = key || handler; if (element[type + key]) return false; if (typeof element.addEventListener != "undefined") { element[type + key] = handler; element.addEventListener(type, handler, false); } else { element['e' + type + key] = handler; element[type + key] = function () { element['e' + type + key](window.event); }; element.attachEvent('on' + type, element[type + key]); } return true; }, removeEvent: function (element, type, key) { if (!element[type + key]) return false; if (typeof element.removeEventListener != "undefined") { element.removeEventListener(type, element[type + key], false); } else { element.detachEvent("on" + type, element[type + key]); element['e' + type + key] = null; } element[type + key] = null; return true; },
這兩個函數(shù)兼容性寫法有很多,結合了很多大牛的寫法后我用的上面版本,這么些看似很復雜,實際上主要解決了上面提到的、除了多個事件處理程序執(zhí)行順序問題的瀏覽器兼容性問題,比較難看懂的IE綁定部分就是為了處理this而寫的。
在使用的時候,可以顯示傳入一個key用于內部識別綁定函數(shù),如果不綁定則使用handler本身作為key,所以可以這么用
function(){},'test'); ssLib.removeEvent(element,'click','test'); function handler(){} ssLib.addEvent(element,'click',handler); ssLib.removeEvent(element,'click',handler);
這個是看到jQuery的on/delegate和YUI 的delegate后萌發(fā)的想法,不過平時老用人家的沒自己寫過,倉促寫了一個,感慨頗多,還是jQuery好使,這個版本目前有一定問題,明天優(yōu)化一下
on: function (parent, type, handler,validater,key) { var _key=key || handler; parent['on'+type+_key]=function (e) { var target = ssLib.getTarget(e); var isFire = validater(target); if (isFire) { target[type + _key] = handler; target[type + _key](e); } }; ssLib.addEvent(parent, type,parent['on'+type+_key] , key); }, off: function (parent, type, key) { if(typeof key=='function'){ ssLib.removeEvent(parent, type, parent['on'+type+key]); }else{ ssLib.removeEvent(parent, type, key); } parent['on'+type+key]=null; }
寫法和剛才類似,不停的繞來繞去也是解決this問題,可以這么用
<div id="test"> <div id="t1">T1</div> <div id="t2">T2</div> </div>
var parent = document.getElementById('test'); var handler=function () { alert(this.id); } var validater=function (obj) { if(obj.parentNode.id=='test'){ return true; }else{ return false; } } ss.on(parent, 'click', handler, validater); ss.off(parent,'click',handler); ss.on(parent, 'click', handler, validater,'delegate'); ss.off(parent,'click','delegate');
用過jQuery的同學肯定知道這個函數(shù),寫自己庫的時候是各種驚羨啊,于是乎加到了自己的庫里
ready: function (fn) { if (document.addEventListener) { document.addEventListener("DOMContentLoaded", function () { document.removeEventListener("DOMContentLoaded", arguments.callee, false);// 防止多次調用 fn(); }, false); } else if (document.addEvent) { var doc = window.document, done = false; // only fire once var init = function () { if (!done) { done = true; fn(); } }; // polling for no errors (function () { try { // throws errors until after ondocumentready doc.documentElement.doScroll('left');// 文檔加載完成后此方法可用 } catch (e) { setTimeout(arguments.callee, 50); return; } // no errors, fire init(); })(); // trying to always fire before onload doc.onreadystatechange = function () { if (doc.readyState == 'complete') { doc.onreadystatechange = null; init(); } }; } }
要想看懂上面代碼最好看看An alternative for DOMContentLoaded on Internet Explorer
今天太晚了要去睡覺了,明天會優(yōu)化一下代碼并解釋一下ready函數(shù)
來自: 昵稱10504424 > 《工作》
0條評論
發(fā)表
請遵守用戶 評論公約
DrawingManager.js
169 * @grammar obj.addEventListener(type, handler[, key])170 * @param {string} type 自定義事件的名稱171 * @param {Function} handler 自定義事...
移動端事件介紹
var EventUtil = { addHandler: function(element,type,handler) { if(element.addEventListener) { element.addEventListener(type,han...
Dom事件介紹
二、事件處理程序1、HTML事件處理程序: 2、DOM0級事件處理程序3、DOM2級事件處理程序DOM2級事件定義了兩個方法:用于處理指定和刪除事...
史上最詳細的JavaScript事件使用指南
DOM2級事件規(guī)定的事件流包括三個階段,分別是:事件捕獲階段,處于目標階段和事件冒泡階段。注意:attachEvent的事件名稱是onclick,而a...
JavaScript事件(事件類型、事件目標、事件處理程序、事件對象、事件流)
//只會輸出 btn1 btn2myBtn.onclick=function(event){console.log("btn1");event.stopPropagation();};myBtn.addEventListener("click",function(event){console.log("btn2&q...
Overview of the Prototype Javascript Library
The containers are HTML elements, and then when the response is received from the server, the element‘s innerHTML is set to be the reponse, or if the options.insertion function is set to...
JavaScript 中綁定事件監(jiān)聽函數(shù)的通用方法[ addEvent() ]_一直想殺你...
JavaScript 中綁定事件監(jiān)聽函數(shù)的通用方法[ addEvent() ]_一直想殺你...JavaScript 中綁定事件監(jiān)聽函數(shù)的通用方法[ addEvent() ]2010-06-13 13:43.function removeEvent(element, type, handler) {if (...
Qt 4.7: QML Keys Element
Qt 4.7: QML Keys ElementQML Keys Element.TextInput key handlingItems specified in forwardTospecific key handlers, e.g.This can be useful when you want one item to handle some keys (e.g. t...
"this" of JavaScript
element.onclick = doSomethingelement.addEventListener(‘click‘, doSomething, false)element.onclick = function() {this.style.co...
微信掃碼,在手機上查看選中內容