javascript事件委托的方式綁定詳解
js事件綁定
事件綁定,這里使用了冒泡的原理,從點(diǎn)擊的元素開(kāi)始,遞歸方式的向父元素傳播事件,這樣做的好處是對(duì)于大量要處理的元素,不必為每個(gè)元素都綁定事件,只需要在他們的父元素上綁定一次即可,提高性能。還有一個(gè)好處就是可以處理動(dòng)態(tài)插入dom中的元素,直接綁定的方式是不行的。
之前一直使用的是jquery的on方法做這樣的事情,前幾天看到公司項(xiàng)目中有實(shí)現(xiàn)這種方式的源代碼,拿來(lái)仔細(xì)研究研究,跟大家分享分享。
function $bindAction(dom, event, listeners) {
#這里的dom為綁定事件的元素,比如document.body
#event為綁定的事件,比如click
#listeners是待執(zhí)行的事件對(duì)象
$addEvent(dom, event, function(e) {
#這里獲取事件e
#獲取點(diǎn)擊的元素src
var e = e || window.event,
src = e.target || e.srcElement,
action,
returnVal;
#模擬冒泡的方式,先是src,然后是src.parentNode,再然后是src.parentNode.parent.Node
#當(dāng)前dom元素等于事件綁定的dom元素的時(shí)候,停止“冒泡”
while (src && src !== dom) {
#循環(huán)獲取dom元素的attr-action屬性,
action = src.getAttribute('attr-action');
#如果當(dāng)前dom元素存在attr-action屬性,并且事件對(duì)象中有該屬性值的函數(shù),執(zhí)行這個(gè)函數(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é)點(diǎn)
src = src.parentNode;
}
});
};
function $addEvent(obj, type, handle) {
if(!obj || !type || !handle) {
return;
}
#綁定事件到多個(gè)對(duì)象,遞歸調(diào)用
if( obj instanceof Array) {
for(var i = 0, l = obj.length; i < l; i++) {
$addEvent(obj[i], type, handle);
}
return;
}
#綁定多個(gè)事件,遞歸調(diào)用
if( type instanceof Array) {
for(var i = 0, l = type.length; i < l; i++) {
$addEvent(obj, type[i], handle);
}
return;
}
#下面這一大段用來(lái)記錄當(dāng)前頁(yè)面一共綁定了多少個(gè)事件,以及事件的相關(guān)信息
#以及某個(gè)對(duì)象上面綁定的事件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
}
}
#這個(gè)里面的apply是為了修改綁定事件所執(zhí)行函數(shù)中的this
#這個(gè)在低版本的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;
}
};
看個(gè)例子:
當(dāng)點(diǎn)擊前三個(gè)的時(shí)候會(huì)依次彈出classname,其他的都不會(huì)觸發(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>
效果如下:

再看看事件的綁定情況,跟我們綁定事件的情況一致:

以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。
相關(guān)文章
一個(gè)php+js實(shí)時(shí)顯示時(shí)間問(wèn)題
本文給大家分享的是解決的php+js實(shí)時(shí)顯示時(shí)間問(wèn)題,主要是自己當(dāng)時(shí)的理解有問(wèn)題,也許大家有和我一樣的情況,這里分享給大家2015-10-10
JS常用正則表達(dá)式總結(jié)【經(jīng)典】
這篇文章主要介紹了JS常用正則表達(dá)式,總結(jié)分析了常見(jiàn)的數(shù)字、字符、郵箱、身份證、電話等的正則驗(yàn)證技巧,需要的朋友可以參考下2017-05-05
JS簡(jiǎn)單添加元素新節(jié)點(diǎn)的方法示例
這篇文章主要介紹了JS簡(jiǎn)單添加元素新節(jié)點(diǎn)的方法,結(jié)合實(shí)例形式分析了javascript針對(duì)頁(yè)面元素節(jié)點(diǎn)的創(chuàng)建、添加、克隆等相關(guān)操作技巧,需要的朋友可以參考下2018-02-02
Jquery+javascript實(shí)現(xiàn)支付網(wǎng)頁(yè)數(shù)字鍵盤(pán)
這篇文章主要為大家詳細(xì)介紹了Jquery+javascript實(shí)現(xiàn)支付網(wǎng)頁(yè)數(shù)字鍵盤(pán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
Easyui Tree獲取當(dāng)前選擇節(jié)點(diǎn)的所有頂級(jí)父節(jié)點(diǎn)
這篇文章主要介紹了Easyui Tree獲取當(dāng)前選擇節(jié)點(diǎn)的所有頂級(jí)父節(jié)點(diǎn),以及easyUI Tree顯示選中節(jié)點(diǎn)的所有父節(jié)點(diǎn)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-02-02
javascript實(shí)現(xiàn)九宮格相加數(shù)值相等
這篇文章主要介紹了javascript實(shí)現(xiàn)九宮格相加數(shù)值相等的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02
js實(shí)現(xiàn)鼠標(biāo)滑過(guò)文字鏈接色彩變化的效果
這篇文章主要介紹了js實(shí)現(xiàn)鼠標(biāo)滑過(guò)文字鏈接色彩變化的效果,涉及javascript鼠標(biāo)事件及樣式操作的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-05-05
原生js仿jquery animate動(dòng)畫(huà)效果
這篇文章主要為大家詳細(xì)介紹了原生js仿jquery animate動(dòng)畫(huà)效果,具有一定的,感興趣的小伙伴們可以參考一下2016-07-07
js自動(dòng)滑動(dòng)+鼠標(biāo)滑動(dòng)區(qū)域
js自動(dòng)滑動(dòng)+鼠標(biāo)滑動(dòng)區(qū)域...2007-08-08
JavaScript實(shí)現(xiàn)刮刮樂(lè)效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)刮刮樂(lè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11

