JS事件監(jiān)聽與事件委托舉例詳解(前端小白必學(xué))
一.什么是事件監(jiān)聽?
在JavaScript中,事件監(jiān)聽是一種允許你響應(yīng)用戶操作或其他瀏覽器事件(如點(diǎn)擊、鍵盤輸入、頁(yè)面加載等)的機(jī)制
在JS中若要進(jìn)行事件的監(jiān)聽,dom元素發(fā)生驅(qū)動(dòng)行為也可以使用事件綁定的方法,這種方法直觀,但通常不推薦用于大型或復(fù)雜的項(xiàng)目中,因?yàn)樗鼤?huì)導(dǎo)致HTML和JavaScript代碼的混合,不利于代碼的維護(hù)和分離。
舉個(gè)例子(下面代碼采用了事件綁定的方式對(duì)box這個(gè)dom元素進(jìn)行點(diǎn)擊行為)
var box = document.querySelector(".box");
// 2事件綁定 只執(zhí)行最后一次
box.onclick = function () {
console.log("111");
};
box.onclick = function () {
console.log("222");
};
box.onclick = function () {
console.log("333"); //333
};在控制臺(tái)點(diǎn)擊了box這個(gè)dom元素,我們發(fā)現(xiàn)只打印輸出了333這段代碼。
為什么會(huì)出現(xiàn)這種情況呢?
在javaScript中給同個(gè)dom元素用事件綁定的方式對(duì)dom元素綁定多個(gè)行為,它會(huì)覆蓋之前的驅(qū)動(dòng)事件,只執(zhí)行最后一次事件行為,這就是為什么只出現(xiàn)333,而不出現(xiàn)111,222的原因。
那么我們就可以使用(addEventListener)對(duì)事件進(jìn)行監(jiān)聽,監(jiān)聽到的事件每一次都能執(zhí)行。
box.addEventListener("click", function () {
console.log("111"); //111
});
box.addEventListener("click", function () {
console.log("222"); //222
});
box.addEventListener("click", function () {
console.log("333"); //333
});在上面的代碼中,在控制臺(tái)的輸出是111,222,333
二.理解嵌套關(guān)系的事件綁定和監(jiān)聽
//在html body內(nèi)書寫三個(gè)嵌套標(biāo)簽
<div class="one">
<div class="two">
<div class="three"></div>
</div>
</div>
<script>
//獲取標(biāo)簽
var one=document.querySelector('.one')
var two=document.querySelector('.two')
var three=document.querySelector('.three')
// 2)事件綁定 (從里往外依次執(zhí)行事件) three two one
one.onclick=function(){
console.log('one');
}
two.onclick=function(){
console.log('two');
}
three.onclick=function(){
console.log('three');
}
// 3)事件監(jiān)聽(第三個(gè)參數(shù)不填時(shí)默認(rèn)是false,默認(rèn)是事件冒泡) three two one
one.addEventListener('click',function(){
console.log('one');
},false)
two.addEventListener('click',function(){
console.log('two');
},false)
three.addEventListener('click',function(){
console.log('three');
},false)
// 輸入的是true,則從外到內(nèi)監(jiān)聽,屬于捕獲行為 one two three
one.addEventListener('click',function(){
console.log('one');
},true)
two.addEventListener('click',function(){
console.log('two');
},true)
three.addEventListener('click',function(){
console.log('three');
},true)
</script>可以看到在標(biāo)簽中one包著two,two包著three;點(diǎn)擊three盒子,在事件綁定中,從里到外執(zhí)行事件,先執(zhí)行three、two、one。在事件監(jiān)聽中,不填false,默認(rèn)是冒泡行為。輸入的是true,從外到內(nèi)監(jiān)聽,屬于捕獲行為。在控制臺(tái)上輸出是one、two、three
三.如何阻止事件捕獲和事件冒泡?
1.事件捕獲
// 4)阻止事件捕獲 function要添加參數(shù) one two three
one.addEventListener('click',function(e){
// 阻止事件捕獲(阻止監(jiān)聽同一事件的其他事件監(jiān)聽器被調(diào)用)
e.stopImmediatePropagation()
console.log('one');
},true)
two.addEventListener('click',function(){
console.log('two');
},true)
three.addEventListener('click',function(){
console.log('three');
},true)2.事件冒泡
// 5)阻止事件冒泡 //three two one
one.addEventListener('click',function(){
console.log('one');
},false)
two.addEventListener('click',function(){
console.log('two');
},false)
three.addEventListener('click',function(e){
// 阻止其他事件監(jiān)聽器被調(diào)用
e.stopPropagation()
console.log('three');
},false)四.什么是事件委托?
事件委托就是把原本要綁定在子元素上的事件綁定在父元素的身上,通過(guò)事件對(duì)象上的target屬性去判斷是哪一個(gè)子元素觸發(fā)了事件,再進(jìn)行相應(yīng)的操作。使用事件委托可以減少dom操作,優(yōu)化web性能,可以動(dòng)態(tài)的對(duì)元素的添加和移除實(shí)現(xiàn)動(dòng)態(tài)元素的綁定 。
當(dāng)子元素上的事件被觸發(fā)時(shí),由于事件冒泡機(jī)制,這個(gè)事件會(huì)冒泡到父元素或祖先元素,從而觸發(fā)在父元素或祖先元素上設(shè)置的事件監(jiān)聽函數(shù)。然后,通過(guò)判斷事件發(fā)生的元素DOM類型,父元素或祖先元素可以做出不同的響應(yīng)。
<ol>
<li class="active">導(dǎo)航1</li>
<li>導(dǎo)航2</li>
<li>導(dǎo)航3</li>
<li>導(dǎo)航4</li>
<li>導(dǎo)航5</li>
</ol>
<!-- 事件委托 本應(yīng)該給li標(biāo)簽綁定事件的,結(jié)果給li標(biāo)簽的父元素或者祖先元素綁定事情 -->
<script>
// 獲取ol標(biāo)簽
var ol = document.querySelector("ol");
// ol這個(gè)父元素綁定事件
ol.onclick = function (event) {
// 1.獲取事件源
var el = event.target;
console.dir(el);
// 2. 判斷點(diǎn)擊的標(biāo)簽是否為li標(biāo)簽,為li標(biāo)簽設(shè)置高亮
if (el.tagName === "LI") {
for (var j = 0; j < ol.children.length; j++) {
ol.children[j].className = "";
}
el.className = "active";
}
};
</script>
在上面代碼中對(duì)ol綁定了事件監(jiān)聽,可以通過(guò)target去獲取事件源,事件對(duì)象就是觸發(fā)事件所產(chǎn)生的數(shù)據(jù)集合。
如此一個(gè)tab選項(xiàng)卡就完成了

事件委托可以動(dòng)態(tài)添加(添加了元素可以同樣動(dòng)態(tài)綁定了事件)
例子:
// 事件委托可以動(dòng)態(tài)添加
// 創(chuàng)建一個(gè)li標(biāo)簽
var li = document.createElement("li");
li.innerHTML = "導(dǎo)航6";
ol.appendChild(li);
如此,動(dòng)態(tài)添加的導(dǎo)航6元素就可以使用ol所綁定的事件啦。
事件委托的好處 ?
1.提高性能:事件委托通過(guò)減少需要綁定的事件監(jiān)聽器的數(shù)量,來(lái)優(yōu)化性能。只需在父級(jí)或祖先元素上添加一個(gè)事件處理程序,就可以管理其所有后代元素上的同一類型事件,這樣就降低了內(nèi)存占用。
2.動(dòng)態(tài)監(jiān)聽:對(duì)于動(dòng)態(tài)添加到頁(yè)面中的元素,由于它們的事件監(jiān)聽器是綁定在父級(jí)或祖先元素上的,因此這些新元素也能自動(dòng)獲得事件監(jiān)聽功能,無(wú)需重新綁定事件。
3.避免內(nèi)存泄漏:在低版本的IE瀏覽器中,如果刪除元素而沒(méi)有移除事件監(jiān)聽器,可能會(huì)導(dǎo)致內(nèi)存泄漏。而使用事件委托,由于事件監(jiān)聽器是綁定在父級(jí)或祖先元素上的,即使子元素被刪除,也不會(huì)影響事件監(jiān)聽器的存在,從而避免了內(nèi)存泄漏的問(wèn)題。
事件委托是一種強(qiáng)大且靈活的事件處理機(jī)制,特別適用于需要處理大量相似元素或動(dòng)態(tài)添加元素的情況。
總結(jié)
到此這篇關(guān)于JS事件監(jiān)聽與事件委托舉例詳解的文章就介紹到這了,更多相關(guān)JS事件監(jiān)聽與事件委托內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS仿京東移動(dòng)端手指撥動(dòng)切換輪播圖效果
這篇文章主要為大家詳細(xì)介紹了JS仿京東移動(dòng)端手指撥動(dòng)切換輪播圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
JavaScript實(shí)現(xiàn)簡(jiǎn)易tab欄切換內(nèi)容欄
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡(jiǎn)易tab欄切換內(nèi)容欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
js中判斷對(duì)象是否為空的三種實(shí)現(xiàn)方法
本篇文章主要是對(duì)js中判斷對(duì)象是否為空的三種實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12
CSS+JS實(shí)現(xiàn)點(diǎn)擊文字彈出定時(shí)自動(dòng)關(guān)閉DIV層菜單的方法
這篇文章主要介紹了CSS+JS實(shí)現(xiàn)點(diǎn)擊文字彈出定時(shí)自動(dòng)關(guān)閉DIV層菜單的方法,設(shè)計(jì)javascript操作菜單的彈出與關(guān)閉的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05
基于JavaScript實(shí)現(xiàn)的插入排序算法分析
這篇文章主要介紹了基于JavaScript實(shí)現(xiàn)的插入排序算法,結(jié)合實(shí)例形式詳細(xì)分析了插入排序的原理、操作步驟及javascript相關(guān)實(shí)現(xiàn)技巧與注意事項(xiàng),需要的朋友可以參考下2017-04-04
uniapp實(shí)現(xiàn)全局設(shè)置字體大小(小中大的字體切換)
隨著UniApp的流行,越來(lái)越多的開發(fā)者選擇使用它來(lái)構(gòu)建跨平臺(tái)應(yīng)用程序,下面這篇文章主要給大家介紹了關(guān)于uniapp實(shí)現(xiàn)全局設(shè)置字體大小(小中大的字體切換)的相關(guān)資料,需要的朋友可以參考下2023-06-06
微信小程序頁(yè)面跳轉(zhuǎn)功能之從列表的item項(xiàng)跳轉(zhuǎn)到下一個(gè)頁(yè)面的方法
這篇文章主要介紹了微信小程序頁(yè)面跳轉(zhuǎn)功能之從列表的item項(xiàng)跳轉(zhuǎn)到下一個(gè)頁(yè)面的方法,結(jié)合具體實(shí)例形式總結(jié)分析了微信小程序頁(yè)面跳轉(zhuǎn)及列表item項(xiàng)跳轉(zhuǎn)頁(yè)面的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11

