JS里關於事件的常被考察的知識點:事件流、事件廣播、原生JS實現事件代理


1、JS里面的事件流

  DOM2級事件模型中規定了事件流的三個階段:捕獲階段、目標階段、冒泡階段,低版本IE(IE8及以下版本)不支持捕獲階段

  捕獲事件流:Netscape提出的事件流,即事件由頁面元素接收,逐級向下,傳播到最具體的元素。

  冒泡事件流:IE提出的事件流,即事件由最具體的元素接收,逐級向上,傳播到頁面。

  關於js事件,這里有一篇非常詳細的介紹,可以看下:http://www.cnblogs.com/hyaaon/p/4630128.html

2、IE和W3C不同綁定事件解綁事件的方法有什么區別,參數分別是什么,以及事件對象e有什么區別

  綁定事件:

  W3C:target.addEventListener(event, listener, useCapture);

  event —— 事件類型;

  listener —— 事件觸發時執行的函數;

  useCapture —— 指定事件是否在捕獲或冒泡階段執行,為true時事件句柄在捕獲階段執行,為false(默認false)時,事件句柄在冒泡階段執行。

btn.addEventListener('click',function(){ //do something...
},false)

  對應的事件移除:

removeEventListener(event,function,capture/bubble);

  IE:target.attachEvent(type, listener);

  type - 字符串,事件名稱,含“on”,比如“onclick”、“onmouseover”、“onkeydown”等。

  listener —— 實現了 EventListener 接口或者是 JavaScript 中的函數。

btn.attachEvent('onclick',function(){ //do something...
})

  對應的事件移除:

detachEvent(event,function);

3、事件的委托(代理 Delegated Events)的原理以及優缺點

  委托(代理)事件是那些被綁定到父級元素的事件,但是只有當滿足一定匹配條件時才會被挪。這是靠事件的冒泡機制來實現的,

  優點是:

  (1)可以大量節省內存占用,減少事件注冊,比如在table上代理所有td的click事件就非常棒 

  (2)可以實現當新增子對象時無需再次對其綁定事件,對於動態內容部分尤為合適

  缺點是:

  事件代理的應用常用應該僅限於上述需求下,如果把所有事件都用代理就可能會出現事件誤判,即本不應用觸發事件的被綁上了事件。

var toolbar = document.querySelector(".toolbar"); toolbar.addEventListener("click", function(e) { var button = e.target; if(!button.classList.contains("active")) button.classList.add("active"); else button.classList.remove("active"); });

4、手寫原生js實現事件代理,並要求兼容瀏覽器

// 簡單的事件委托
function delegateEvent(interfaceEle, selector, type, fn) { if(interfaceEle.addEventListener){ interfaceEle.addEventListener(type, eventfn); }else{ interfaceEle.attachEvent("on"+type, eventfn); } function eventfn(e){ var e = e || window.event; var target = e.target || e.srcElement; if (matchSelector(target, selector)) { if(fn) { fn.call(target, e); } } } } /** * only support #id, tagName, .className * and it's simple single, no combination */ function matchSelector(ele, selector) { // if use id
    if (selector.charAt(0) === "#") { return ele.id === selector.slice(1); } // if use class
    if (selector.charAt(0) === ".") { return (" " + ele.className + " ").indexOf(" " + selector.slice(1) + " ") != -1; } // if use tagName
    return ele.tagName.toLowerCase() === selector.toLowerCase(); } //調用
var odiv = document.getElementById("oDiv"); delegateEvent(odiv,"a","click",function(){ alert("1"); })

5、事件如何派發也就是事件廣播(dispatchEvent)

  一般我們在元素上綁定事件后,是靠用戶在這些元素上的鼠標行為來捕獲或者觸發事件的,或者自帶的瀏覽器行為事件,比如click,mouseover,load等等,有些時候我們需要自定義事件或者在特定的情況下需要觸發這些事件。這個時候我們可以使用IE下fireEvent方法,高級瀏覽器(chrome,firefox等)有dispatchEvent方法

  IE下的例子:

//document上綁定自定義事件ondataavailable
document.attachEvent('ondataavailable', function (event) { alert(event.eventType); }); var obj=document.getElementById("obj"); //obj元素上綁定click事件
obj.attachEvent('onclick', function (event) { alert(event.eventType); }); //調用document對象的createEventObject方法得到一個event的對象實例。
var event = document.createEventObject(); event.eventType = 'message'; //觸發document上綁定的自定義事件ondataavailable
document.fireEvent('ondataavailable', event); //觸發obj元素上綁定click事件
document.getElementById("test").onclick = function () { obj.fireEvent('onclick', event); };

  高級瀏覽器(chrome,firefox等)的例子:

//document上綁定自定義事件ondataavailable
document.addEventListener('ondataavailable', function (event) { alert(event.eventType); }, false); var obj = document.getElementById("obj"); //obj元素上綁定click事件
obj.addEventListener('click', function (event) { alert(event.eventType); }, false); //調用document對象的 createEvent 方法得到一個event的對象實例。
var event = document.createEvent('HTMLEvents'); // initEvent接受3個參數// 事件類型,是否冒泡,是否阻止瀏覽器的默認行為
event.initEvent("ondataavailable", true, true); event.eventType = 'message'; //觸發document上綁定的自定義事件ondataavailable
document.dispatchEvent(event); var event1 = document.createEvent('HTMLEvents'); event1.initEvent("click", true, true); event1.eventType = 'message'; //觸發obj元素上綁定click事件
document.getElementById("test").onclick = function () { obj.dispatchEvent(event1); };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM