事件冒泡
簡單的講,當子元素的事件處理函數被觸發(如onclick),該事件會從事件源(當前子元素)逐級向上層元素傳遞,觸發祖先元素的 onclik 事件,一直到最外層 html 根元素。
這可能會帶來困擾,不必要的事件處理函數被執行了,不過我們可以阻止事件冒泡。事件觸發時,會傳入一個event對象,它有一個 stopPropagation() 方法可以阻止事件冒泡。
事件冒泡機制當然也有有利的一面,事件代理就是基於瀏覽器的事件冒泡機制。
事件代理
事件代理也叫事件委托,當我們需要為父元素的很多子元素添加事件時,可以通過把事件添加到父元素並把事件委托給父元素來觸發事件處理函數。
在開發中,我們有時會遇到給列表每一個子元素都添加一個事件,可以用遍歷來操作,這種方法固然簡單,但是如果這個列表有巨量的子元素的時候,就要消耗大量的性能,並且當子元素需要新增的時候,每增加一個子元素就需要遍歷一次,這種方法就更不可取。
事件委托不僅實現相同了功能,而且大大減少了DOM操作。
<ul class="wrap"> <li class="item">1111<button>刪除</button></li> <li class="item">2222<button>刪除</button></li> <li class="item">3333<button>刪除</button></li> <li class="item">4444<button>刪除</button></li> <li class="item">5555<button>刪除</button></li> </ul> <button class="add">添加子元素</button> <script> let oWrap = document.getElementsByClassName('wrap')[0]; let oItem = document.getElementsByClassName('item'); let oAdd = document.getElementsByClassName('add')[0]; oWrap.addEventListener('click',function(e){ //判斷事件目標元素是否為 li ,並顯示它的第一個子節點的文本內容 if(e.target && e.target.nodeName.toLowerCase() == 'li'){ console.log(e.target.childNodes[0].textContent); } //判斷事件目標元素是否為 button ,刪除它的父元素 if(e.target && e.target.nodeName.toLowerCase() == 'button'){ oWrap.removeChild(e.target.parentNode); } }) //添加子節點 oAdd.addEventListener('click',function () { let oLi = document.createElement('li'); oLi.setAttribute('class','item'); oLi.innerHTML = oItem.length+1+'<button>刪除</button>'; oWrap.appendChild(oLi); }) </script>