說是面試題,其實也至關因而對js事件部分知識點的一個總結。簡單內容一筆帶過,瞭解詳情我都給出了參考連接,都是以前寫的一些相關文章。JavaScript自己沒有事件模型,可是環境能夠有。html
DOM:addEventListener、removeEventListener、dispatchEvent
IE-DOM:attachEvent、detachEvent、fireEvent
jQuery:on、off、trigger前端
捕獲、處於目標階段、冒泡階段(IE8如下只支持冒泡)面試
瞭解更多可參考:事件流數組
標準:瀏覽器
/* 參數: eventName:事件的名字 function:事件處理函數 Boolean:捕獲或者冒泡,默認是false冒泡 */ /*事件對象e做爲參數傳入*/ addEventListener(eventName,function(e){ },false);
IE8如下dom
/* 參數: onEvnet:是事件處理程序的名字,而不是事件名,就是說在事件名前加上on function:事件處理函數 */ /* e=window.event,事件event是window的一個屬性 */ attachEvent(onEventName,function(){ var e=window.event; })
瞭解更多能夠參考事件處理程序ide
原理:靠事件冒泡實現的函數
優勢:學習
缺點:測試
適用於表格/列表等重複性dom元素,事件代理用很差可能出現事件誤判,即本不該該觸發事件的元素被綁定了事件
要求:兼容瀏覽器
考點:事件對象e,IE下事件對應的屬性名。
重點是要說到target,currentTarget以及IE下的srcElement和this。
3、四2部分具體可參考:事件的典型應用事件代理
核心需求:能夠對某一個事件名稱綁定多個事件處理函數,而後觸發這個事件名稱時,依次按照綁定順序觸發相應的事件處理函數。
原理:寫一個類或者匿名函數,有兩個函數,一個bind,一個trigger,分別實現綁定事件和觸發事件。
在bind和trigger函數外層做用域建立一個字典對象,用於存儲註冊的事件名稱和事件處理函數列表。
bind時,若是字典沒有則建立一個,key是事件名稱,value是數組,裏面放着當前註冊的響應函數。
若是字段彙總有,那麼就直接push到數組中便可。
trigger時調出來依次觸發事件響應函數便可。
還有不少細節:
觸發響應函數時的上下文應該是什麼?【我以爲應該就是誰觸發了這個事件處理函數this就是誰,你們有懂的能夠評論一下】
觸發響應函數的參數列表應該是什麼?
若是要求把trigger的參數列表都傳到響應函數中還要考慮把arguments對象轉化爲純數組才行。
js中自定義事件模型
function Emitter() { this._listener = {}; //_listener[自定義的事件名] = [所用執行的匿名函數1, 所用執行的匿名函數2] } //註冊事件 Emitter.prototype.bind = function(eventName, funCallback) { var listenersArr = this._listener[eventName] || []; ////this._listener[eventName]沒有值則將listener定義爲[](數組)。 listenersArr.push(funCallback); this._listener[eventName] = listenersArr; } //觸發事件 Emitter.prototype.trigger = function(eventName) { //未綁定事件 if (!this._listener.hasOwnProperty(eventName)) { console.log('you do not bind this event'); return; } var args = Array.prototype.slice.call(arguments, 1); ////args爲得到除了eventName後面的參數(最後被用做註冊事件的參數) var listenersArr = this._listener[eventName]; var _this = this; if (!Array.isArray(listenersArr)) return; ////自定義事件名不存在 listenersArr.forEach(function(callback) { try { callback.call(_this, args); } catch (e) { console.log(e); } }); } //解綁 Emitter.prototype.unbind = function(eventName, callback) { this._listener.hasOwnProperty(eventName) && delete this._listener[eventName]; callback && callback(); }
測試用例
var emitter = new Emitter(); emitter.bind("selfEvent", function() { console.log("第一個綁定"); Array.prototype.forEach.call(arguments, function(item) { console.log(item); }); }); emitter.bind("selfEvent", function() { console.log("第二個綁定"); Array.prototype.forEach.call(arguments, function(item) { console.log(item); }); }); emitter.trigger('selfEvent', 'a', 'b', 'c'); emitter.unbind('selfEvent', function() { console.log("解除綁定"); }); emitter.trigger('selfEvent', 'a', 'b', 'c');
運行結果
dispatchEvent是js的事件觸發器,事件觸發器就是用來觸發某個元素下的某個事件。
能夠自定義事件,經過觸發器觸發。
<p id="pElement">事件被觸發後文字變紅</p> <script> var pElement=document.getElementById("pElement"); var event=new Event('selfEvent'); pElement.addEventListener('selfEvent', function (e) { alert(e.type); //selfEvent this.style.color="red"; },false); pElement.dispatchEvent(event); </script>
若是初始化自定義事件時須要添加一些額外的數據,能夠用CustomEvent構造函數。
var event=new CustomEvent('lxyEvent',{'detail':'liuxiaoyan'}); //detail屬性值即自定義數據 pElement.addEventListener('lxyEvent', function (e) { alert(e.type+ e.detail); this.style.color="red"; },false); pElement.dispatchEvent(event);
參考:
http://www.cnblogs.com/pcd12321/p/5223347.html
http://www.cnblogs.com/1wen/p/5640997.html
本文做者starof,因知識自己在變化,做者也在不斷學習成長,文章內容也不定時更新,爲避免誤導讀者,方便追根溯源,請諸位轉載註明出處:http://www.cnblogs.com/starof/p/6767655.html有問題歡迎與我討論,共同進步。