javascript事件委托的方式綁定詳解
js事件綁定
事件綁定,這里使用了冒泡的原理,從點擊的元素開始,遞歸方式的向父元素傳播事件,這樣做的好處是對于大量要處理的元素,不必為每個元素都綁定事件,只需要在他們的父元素上綁定一次即可,提高性能。還有一個好處就是可以處理動態(tài)插入dom中的元素,直接綁定的方式是不行的。
之前一直使用的是jquery的on方法做這樣的事情,前幾天看到公司項目中有實現(xiàn)這種方式的源代碼,拿來仔細(xì)研究研究,跟大家分享分享。
function $bindAction(dom, event, listeners) { #這里的dom為綁定事件的元素,比如document.body #event為綁定的事件,比如click #listeners是待執(zhí)行的事件對象 $addEvent(dom, event, function(e) { #這里獲取事件e #獲取點擊的元素src var e = e || window.event, src = e.target || e.srcElement, action, returnVal; #模擬冒泡的方式,先是src,然后是src.parentNode,再然后是src.parentNode.parent.Node #當(dāng)前dom元素等于事件綁定的dom元素的時候,停止“冒泡” while (src && src !== dom) { #循環(huán)獲取dom元素的attr-action屬性, action = src.getAttribute('attr-action'); #如果當(dāng)前dom元素存在attr-action屬性,并且事件對象中有該屬性值的函數(shù),執(zhí)行這個函數(shù) #將事件e、當(dāng)前dom元素、元素的屬性attr-action值傳給要執(zhí)行的函數(shù) if (listeners[action]) { returnVal = listeners[action]({ src : src, e : e, action : action }); #如果上面的函數(shù)執(zhí)行之后返回false,停止繼續(xù)“冒泡” if (returnVal === false) { break; } } #獲取當(dāng)前dom元素的父元素節(jié)點 src = src.parentNode; } }); }; function $addEvent(obj, type, handle) { if(!obj || !type || !handle) { return; } #綁定事件到多個對象,遞歸調(diào)用 if( obj instanceof Array) { for(var i = 0, l = obj.length; i < l; i++) { $addEvent(obj[i], type, handle); } return; } #綁定多個事件,遞歸調(diào)用 if( type instanceof Array) { for(var i = 0, l = type.length; i < l; i++) { $addEvent(obj, type[i], handle); } return; } #下面這一大段用來記錄當(dāng)前頁面一共綁定了多少個事件,以及事件的相關(guān)信息 #以及某個對象上面綁定的事件id window.__allHandlers = window.__allHandlers || {}; window.__Hcounter = window.__Hcounter || 0; function setHandler(obj, type, handler, wrapper) { obj.__hids = obj.__hids || []; var hid = 'h' + ++window.__Hcounter; obj.__hids.push(hid); window.__allHandlers[hid] = { type : type, handler : handler, wrapper : wrapper } } #這個里面的apply是為了修改綁定事件所執(zhí)行函數(shù)中的this #這個在低版本的IE中才真正起作用 function createDelegate(handle, context) { return function() { return handle.apply(context, arguments); }; } #綁定事件,記錄事件綁定信息 if(window.addEventListener) { var wrapper = createDelegate(handle, obj); setHandler(obj, type, handle, wrapper) obj.addEventListener(type, wrapper, false); } else if(window.attachEvent) { var wrapper = createDelegate(handle, obj); setHandler(obj, type, handle, wrapper) obj.attachEvent("on" + type, wrapper); } else { obj["on" + type] = handle; } };
看個例子:
當(dāng)點擊前三個的時候會依次彈出classname,其他的都不會觸發(fā)事件
<style type="text/css"> #out{width: 500px;background-color: #CDE} #inner{background-color: #ABCDEF;margin: 0;padding: 0;width: 400px;} ul{background-color: pink;margin: 0;padding: 0;width: 400px;} li{width:398px;height: 20px;border: 1px solid black;margin: 15px 0px;padding: 0px;list-style: none;} </style> div#out > div#inner : <div id="out"> <ul id="inner"> <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li> <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li> <li class="lib" attr-action="setWhat">class="lia" attr-action="setWhat"</li> <li class="lib">class="lib"</li> <li class="lib">class="lib"</li> <li class="lib">class="lib"</li> </ul> </div> ul : <ul> <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li> <li class="lia" attr-action="setWhat">class="lia" attr-action="setWhat"</li> <li class="lib" attr-action="setWhat">class="lia" attr-action="setWhat"</li> <li class="lib">class="lib"</li> <li class="lib">class="lib"</li> <li class="lib">class="lib"</li> </ul> <script> listeners = { setWhat : function(opts) { alert(opts.src.className); return false; }, }; window.onload = function(){$bindAction(document.getElementById('out'), ['click', 'mouseover'], listeners);} </script>
效果如下:
再看看事件的綁定情況,跟我們綁定事件的情況一致:
以上所述就是本文的全部內(nèi)容了,希望大家能夠喜歡。
相關(guān)文章
微信小程序?qū)W習(xí)總結(jié)(一)項目創(chuàng)建與目錄結(jié)構(gòu)分析
這篇文章主要介紹了微信小程序?qū)W習(xí)總結(jié)(一)項目創(chuàng)建與目錄結(jié)構(gòu),總結(jié)分析了微信小程序項目創(chuàng)建、配置方法以及目錄結(jié)構(gòu)、文件功能,需要的朋友可以參考下2020-06-06用JavaScript 處理 URL 的兩個函數(shù)代碼
用JavaScript 處理 URL 的兩個函數(shù)代碼...2007-08-08window.event.keyCode兼容IE和Firefox實現(xiàn)js代碼
window.event.keyCode兼容IE和Firefox具體實現(xiàn)代碼如下,感興趣的朋友可以參考下哈2013-05-05javascript前端和后臺進(jìn)行數(shù)據(jù)交互方法示例
這篇文章主要介紹了javascript前端和后臺進(jìn)行數(shù)據(jù)交互方法示例,文章通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08