JS事件監(jiān)聽與事件委托舉例詳解(前端小白必學)
一.什么是事件監(jiān)聽?
在JavaScript中,事件監(jiān)聽是一種允許你響應用戶操作或其他瀏覽器事件(如點擊、鍵盤輸入、頁面加載等)的機制
在JS中若要進行事件的監(jiān)聽,dom元素發(fā)生驅(qū)動行為也可以使用事件綁定的方法,這種方法直觀,但通常不推薦用于大型或復雜的項目中,因為它會導致HTML和JavaScript代碼的混合,不利于代碼的維護和分離。
舉個例子(下面代碼采用了事件綁定的方式對box這個dom元素進行點擊行為)
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 };
在控制臺點擊了box這個dom元素,我們發(fā)現(xiàn)只打印輸出了333這段代碼。
為什么會出現(xiàn)這種情況呢?
在javaScript中給同個dom元素用事件綁定的方式對dom元素綁定多個行為,它會覆蓋之前的驅(qū)動事件,只執(zhí)行最后一次事件行為,這就是為什么只出現(xiàn)333,而不出現(xiàn)111,222的原因。
那么我們就可以使用(addEventListener)對事件進行監(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 });
在上面的代碼中,在控制臺的輸出是111,222,333
二.理解嵌套關(guān)系的事件綁定和監(jiān)聽
//在html body內(nèi)書寫三個嵌套標簽 <div class="one"> <div class="two"> <div class="three"></div> </div> </div> <script> //獲取標簽 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)聽(第三個參數(shù)不填時默認是false,默認是事件冒泡) 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>
可以看到在標簽中one包著two,two包著three;點擊three盒子,在事件綁定中,從里到外執(zhí)行事件,先執(zhí)行three、two、one。在事件監(jiān)聽中,不填false,默認是冒泡行為。輸入的是true,從外到內(nèi)監(jiān)聽,屬于捕獲行為。在控制臺上輸出是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)
四.什么是事件委托?
事件委托就是把原本要綁定在子元素上的事件綁定在父元素的身上,通過事件對象上的target屬性去判斷是哪一個子元素觸發(fā)了事件,再進行相應的操作。使用事件委托可以減少dom操作,優(yōu)化web性能,可以動態(tài)的對元素的添加和移除實現(xiàn)動態(tài)元素的綁定 。
當子元素上的事件被觸發(fā)時,由于事件冒泡機制,這個事件會冒泡到父元素或祖先元素,從而觸發(fā)在父元素或祖先元素上設(shè)置的事件監(jiān)聽函數(shù)。然后,通過判斷事件發(fā)生的元素DOM類型,父元素或祖先元素可以做出不同的響應。
<ol> <li class="active">導航1</li> <li>導航2</li> <li>導航3</li> <li>導航4</li> <li>導航5</li> </ol> <!-- 事件委托 本應該給li標簽綁定事件的,結(jié)果給li標簽的父元素或者祖先元素綁定事情 --> <script> // 獲取ol標簽 var ol = document.querySelector("ol"); // ol這個父元素綁定事件 ol.onclick = function (event) { // 1.獲取事件源 var el = event.target; console.dir(el); // 2. 判斷點擊的標簽是否為li標簽,為li標簽設(shè)置高亮 if (el.tagName === "LI") { for (var j = 0; j < ol.children.length; j++) { ol.children[j].className = ""; } el.className = "active"; } }; </script>
在上面代碼中對ol綁定了事件監(jiān)聽,可以通過target去獲取事件源,事件對象就是觸發(fā)事件所產(chǎn)生的數(shù)據(jù)集合。
如此一個tab選項卡就完成了
事件委托可以動態(tài)添加(添加了元素可以同樣動態(tài)綁定了事件)
例子:
// 事件委托可以動態(tài)添加 // 創(chuàng)建一個li標簽 var li = document.createElement("li"); li.innerHTML = "導航6"; ol.appendChild(li);
如此,動態(tài)添加的導航6元素就可以使用ol所綁定的事件啦。
事件委托的好處 ?
1.提高性能:事件委托通過減少需要綁定的事件監(jiān)聽器的數(shù)量,來優(yōu)化性能。只需在父級或祖先元素上添加一個事件處理程序,就可以管理其所有后代元素上的同一類型事件,這樣就降低了內(nèi)存占用。
2.動態(tài)監(jiān)聽:對于動態(tài)添加到頁面中的元素,由于它們的事件監(jiān)聽器是綁定在父級或祖先元素上的,因此這些新元素也能自動獲得事件監(jiān)聽功能,無需重新綁定事件。
3.避免內(nèi)存泄漏:在低版本的IE瀏覽器中,如果刪除元素而沒有移除事件監(jiān)聽器,可能會導致內(nèi)存泄漏。而使用事件委托,由于事件監(jiān)聽器是綁定在父級或祖先元素上的,即使子元素被刪除,也不會影響事件監(jiān)聽器的存在,從而避免了內(nèi)存泄漏的問題。
事件委托是一種強大且靈活的事件處理機制,特別適用于需要處理大量相似元素或動態(tài)添加元素的情況。
總結(jié)
到此這篇關(guān)于JS事件監(jiān)聽與事件委托舉例詳解的文章就介紹到這了,更多相關(guān)JS事件監(jiān)聽與事件委托內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實現(xiàn)簡易tab欄切換內(nèi)容欄
這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)簡易tab欄切換內(nèi)容欄,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05CSS+JS實現(xiàn)點擊文字彈出定時自動關(guān)閉DIV層菜單的方法
這篇文章主要介紹了CSS+JS實現(xiàn)點擊文字彈出定時自動關(guān)閉DIV層菜單的方法,設(shè)計javascript操作菜單的彈出與關(guān)閉的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-05-05uniapp實現(xiàn)全局設(shè)置字體大小(小中大的字體切換)
隨著UniApp的流行,越來越多的開發(fā)者選擇使用它來構(gòu)建跨平臺應用程序,下面這篇文章主要給大家介紹了關(guān)于uniapp實現(xiàn)全局設(shè)置字體大小(小中大的字體切換)的相關(guān)資料,需要的朋友可以參考下2023-06-06微信小程序頁面跳轉(zhuǎn)功能之從列表的item項跳轉(zhuǎn)到下一個頁面的方法
這篇文章主要介紹了微信小程序頁面跳轉(zhuǎn)功能之從列表的item項跳轉(zhuǎn)到下一個頁面的方法,結(jié)合具體實例形式總結(jié)分析了微信小程序頁面跳轉(zhuǎn)及列表item項跳轉(zhuǎn)頁面的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11