JavaScript事件冒泡

JavaScript事件中有很是重要的特性——事件冒泡:
閒話少說,讓咱們經過例子來講明一切
觀察下面的代碼:
<div onclick="alert('The handler!')">
  <em>
     If you click on <code>EM</code>, the handler on <code>DIV</code> runs </em> </div>
無論咱們點擊<div>、<em>或<code>時,都會觸發click事件。
 
爲何咱們點擊的是em或code節點會觸發div的click事件?
其實這就是冒泡的特性,冒泡的原理很簡單。
咱們再看一段代碼:
<style>
body * { margin: 10px; border: 1px solid blue; } </style> <form onclick="alert('form')">FORM <div onclick="alert('div')">DIV <p onclick="alert('p')">P</p> </div> </form>
若是咱們點擊 P ,瀏覽器會依次執行alert('p'); alert('div'); alert('form')。
 
這說明,當觸發某個節點上的事件時,它首先會執行本身的事件,而後會找到本身父級div的事件,再到Form,最終這個事件會「冒泡」到水面,即它的祖先即document對象。

 

這個處理的過程 就叫「冒泡」,就像水裏的泡泡,是由下而上的。
 
注意:並非全部的事件都有「冒泡」,例如focus等。
 
 
event.target 與 this的區別:
 
event.target:是查找發起事件的「目標」元素,在冒泡的過程當中它是不會被改變的。
this :指的是當前元素
例如:若是咱們有一個form.onclick的函數,它能夠捕捉form內的全部點擊事件,別管這個點擊事件在form哪裏觸發,它都會冒泡到form這一層而且執行這個onclick函數。
在form.onclick函數裏,this(=event.currentTarget)指的是<form>表單,由於這個event.target 指的是實際被點擊到的表單中的元素。
 
看看下面這個例子,從這個例子能夠更好的理解this與event.target的區別。

 

form.onclick = function(event) {
event.target.style.backgroundColor = 'yellow'; // chrome needs some time to paint yellow setTimeout(() => { alert("target = " + event.target.tagName + ", this=" + this.tagName); event.target.style.backgroundColor = '' }, 0);};
this.tagName:指的是FORM
event.target.tagName:指的是咱們點擊的哪一個元素。
 
阻止冒泡
一般來說, 冒泡事件會從目標元素一直上升到<html>, 而後達到document對象,一些事件會達到window,並會調用「上升過程當中」全部的對應的函數。so,如何阻止冒泡呢?
使用:event.stopPropagation()
<body onclick="alert(`the bubbling doesn't reach here`)">
<button onclick="event.stopPropagation()">Click me</button>
</body>

 

點擊Click me按鈕時,body是不會有alert的動做。
 
event.stopImmediatePropagation()
若是一個元素上綁定了多個事件處理,咱們使用stopPropagation中止掉其中一個冒泡,可是其餘的冒泡仍在執行。
爲了阻止當前元素及綁定事件的冒泡,須要使用event.stopImediatePropagation()函數。
 
注意:
一般沒有必要去阻止泡沫的發生。通常的狀況能夠經過其餘方式來解決。例如利用自定義事件或者能夠將數據寫入到事件的對象中。