js事件冒泡javascript
javascript的事件傳播過程當中,當事件在一個元素上出發以後,事件會逐級傳播給先輩元素,直到document爲止,有的瀏覽器可能到window爲止,這就是事件冒泡現象。html
<div id="col">
<p>
<a id="btn" href="#">button</a>
</p>
</div>java
<script>jquery
let btnclick = document.getElementById('col');
btnclick.onclick=function(e){
console.log('1');
};面試
<script>瀏覽器
執行結果,當點擊a標籤時,也能夠在控制檯輸出1;可是a元素並無綁定click事件,這就是因爲事件冒泡的現象,事件逐級傳播給先輩元素,點擊a——p——div,而後就能夠執行對應的div綁定的事件。dom
特別說明:並非全部的事件都有冒泡現象,好比以下幾個:blur事件 focus事件 load事件性能
js事件委託spa
事件委託又能夠叫事件代理,事件委託就是利用事件冒泡,只指定一個事件處理程序,就能夠管理某一類型的全部事件。代理
事件委託的益處:咱們都知道,減小dom操做能夠提升網頁性能,當一個頁面的父級元素和不少子級元素都須要操做同一件事件的時候,咱們不可能每一個元素都去給它綁定一個事件,看下面例子:
<ul id="getNum"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> <script> let ptclick = document.getElementById('getNum'); let lilist = ptclick.querySelectorAll('li'); for(let i=0;i<lilist.length;i++){ lilist[i].index = i; }; ptclick.onclick = function(e){ var e = e || window.event; var target = e.target || e.srcElement; console.log(e.target.index); }; </script>
點擊每一個li元素都會打印對應的目標li的index值;
可是並非全部的狀況都適用於事件冒泡的,當出現父子級之間的註冊事件不一致時,就不適用。關於事件委託更加詳細的解釋,查https://www.cnblogs.com/liugang-vip/p/5616484.html
每一個例子都很詳細的分析了。
js事件捕獲
事件捕獲剛好與事件冒泡相反,它從頂層祖先元素開始,直到事件觸發元素。
DOM標準同時支持捕獲事件模型和冒泡事件模型,可是,捕獲事件模型先發生。兩種事件流都會觸發DOM中的全部對象,從document對象開始,也在document對象結束。
js事件捕獲通常經過DOM2事件模型addEventListener來實現的:
target.addEventListener(type, listener, useCapture)
第三個參數默認設置爲false,表示在冒泡階段出發事件,設置爲true時表示在捕獲階段觸發,通常咱們工做中彷佛不多使用事件捕獲。但仍是要理解一下,面試過程當中沒少問過這類問題。
分析例子:
<div id="box"> <div id="middle"> <div id="inner"></div> </div> </div> <script> //事件捕獲 window.onload=function(){ let box=document.getElementById("box"); let middle=document.getElementById("middle"); let inner=document.getElementById("inner"); box.addEventListener("click",function(){console.log("box")},true); middle.addEventListener("click",function(){console.log("middle")},true); inner.addEventListener("click",function(){console.log("inner")},true); } </script>
當點擊inner綁定事件時,控制檯會直接輸出,box,middle,inner
js阻止事件冒泡
平時開發過程當中,會用到大量的事件冒泡事件,可是可能咱們在某個子級標籤不須要傳遞事件給父級,這時候就須要阻止它事件的冒泡。
通常,使用stopPropagation來阻止事件的冒泡,IE中使用cancleBuble=true,stopPropagation也是事件對象(Event)的一個方法,做用是阻止目標元素的冒泡事件,可是會不阻止默認行爲。
接上面事件冒泡的例子:
//阻止事件冒泡 let btna = document.getElementById('btn'); btna.onclick=function(e){ window.event? window.event.cancelBubble = true : e.stopPropagation(); };
此時,當點擊a標籤元素時,控制檯就不會再打印出1;
阻止瀏覽器默認行爲
開發過程當中,總會出現各類瀏覽器的默認行爲,這時候就須要阻止瀏覽器的默認行爲,通常狀況下,使用
preventDefault阻止瀏覽器的默認行爲,在IE瀏覽器下,使用returnValue = false;
javascript的return false只會阻止默認行爲,而是用jQuery的話則既阻止默認行爲又防止對象冒泡。
//阻止瀏覽器的默認行爲 function stopDefault( e ) { //通常狀況下 if ( e && e.preventDefault ) e.preventDefault(); //IE中 else window.event.returnValue = false; return false; }