1.什麼是事件流?javascript
事件流所描述的是從頁面中接受事件的順序css
2.DOM事件流的三個階段?html
事件流包括三個階段:事件捕獲階段、處於目標階段、事件冒泡階段java
3.DOM事件流三個階段的執行順序?瀏覽器
首先發生的事件捕獲,爲截取事件提供機會,而後是目標接受事件,最後是事件冒泡階段,因此能夠在最後一個階段對事件做出響應。見下圖更直觀:bash
在dom事件流中,事件的目標在捕獲階段不會接受到事件,這意味着在捕獲階段,事件從 document 到 div 後就中止了。下一個階段是目標階段,因而事件在 div 上發生,並在事件處理中被當作是冒泡階段的一部分, 而後,冒泡階段發生,事件又傳回document。
dom
1.什麼是事件冒泡?
當事件發生後,這個事件就要開始傳播(從裏向外或者從外向裏)函數
2.爲何要傳播?ui
由於事件源自己(可能)並無處理事件的能力,即處理事件的函數(方法)並未綁定在該事件源上。例如咱們點擊一個按鈕時,就會產生一個click事件,但這個按鈕自己可能不能處理這個事件,事件必須從這個按鈕傳播出去,從而到達可以處理這個事件的代碼中(例如咱們給按鈕的onclick屬性賦一個函數的名字,就是讓這個函數去處理該按鈕的click事件),或者按鈕的父級綁定有事件函數,當該點擊事件發生在按鈕上,按鈕自己並沒有處理事件函數,則傳播到父級去處理。spa
小案例代碼以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div>
<button>點擊</button>
</div>
</body>
</html>
複製代碼
(1) button
(2) div
(3) body
(4) html
(5) document
1.爲何要阻止冒泡?
例如:document上有A事件,div有B事件,div裏面的span有C事件,若是不給span和div加阻止事件冒泡的話,點擊span時就會觸發到div的B事件、document的A事件,當點擊span時不想觸發div和document的事件就要加上阻止事件冒泡,div也是同樣的道理,若是咱們不想讓點擊某個事件時父級受到影響,這時就應阻止冒泡。
eg:不加阻止冒泡事件,代碼以下:
css代碼:
<style type="text/css">
.box1{width:200px;height:200px;background:pink;}
.box2{width:100px;height:100px;background:gray;}
</style>複製代碼
js+html代碼:
<body>
<div class="box1">
<div class="box2"></div>
</div>
<script type="text/javascript">
//獲取對象
var box1 = document.getElementsByClassName('box1')[0];
var box2 = document.getElementsByClassName('box2')[0];
//添加事件
box1.onclick = function(){
console.log('您點擊了box1');
}
box2.onclick = function(){
console.log('您點擊了box2');
}
</script>
</body>複製代碼
效果以下:
如圖能夠看出當點擊 box1 時,只會提示‘您點擊了box1’ 而點擊 box2 時,居然輸出了兩句提示,若是咱們不想要這種效果,咱們只想要在點擊了哪一個按鈕後就執行該按鈕的命令,也就是說阻止冒泡。
下面給出上述小案例的阻止冒泡方法:一句代碼搞定,改變 box2 的觸發事件,代碼以下:
box2.onclick = function(e){
console.log('您點擊了box2');
e.stopPropagation();
}複製代碼
效果圖以下:這樣就實現阻止冒泡
2.阻止冒泡的方法。
①event.stopPropagation()方法 (這個方法小編在上面已經給出了例子,這裏就不在給出具體的例子)
這是阻止事件的冒泡方法,不讓事件向documen上蔓延,可是默認事件仍然會執行,當你調用這個方法的時候,若是點擊一個鏈接,這個鏈接仍然會被打開,
②event.preventDefault()方法
這是阻止默認事件的方法,調用此方法是,鏈接不會被打開,可是會發生冒泡,冒泡會傳遞到上一層的父元素;
下面給你們一個小例子:看圖說話,在下面的空白處,不管我怎麼點擊右鍵,不管在什麼位置點擊,都會出現默認的東西,若是咱們不想要這種默認的東西怎麼辦呢?繼續看圖下面的案例,立刻帶你飛,走起-------
eg:阻止瀏覽器右鍵默認事件
css代碼:
<style type="text/css">
*{margin:0;padding:0;}
ul{list-style:none;}
.box{position:relative;width:80px;border:1px solid gray;display: none;}
.box ul li{height:40px;line-height:40px;text-align:center;}
.box ul li:hover{background:#ccc;}
</style>複製代碼
html+js代碼:
<body>
<div class='box'>
<ul>
<li>刷新</li>
<li>刪除</li>
<li>命名</li>
</ul>
</div>
<script type="text/javascript">
//獲取box對象
var box = document.getElementsByClassName('box')[0];
//右鍵鼠標事件
window.oncontextmenu = function(event){
//阻止默認事件
event.preventDefault();
//獲取鼠標點擊某個位置的水平位置 X 和垂直位置 Y
var x=event.clientX;
var y=event.clientY;
//改變 box 距離上面和左邊的位置
box.style.top = y + 'px';
box.style.left = x + 'px';
box.style.display = 'block';
}
window.onclick = function() {
box.style.display = "none";
}
</script>
</body>
複製代碼
效果以下:
③ return false(這裏的例子就不贅述了,有心的小夥伴能夠動手試試)
這個方法比較暴力,他會同時阻止事件冒泡也會阻止默認事件;寫上此代碼,鏈接不會被打開,事件也不會傳遞到上一層的父元素;能夠理解爲return false就等於同時調用了event.stopPropagation()和event.preventDefault()
事件捕獲和事件冒泡是恰好相反的,事件捕獲是指不太具體的節點應該更早的接收到事件,而最具體的節點應該最後接收到事件
案例走起:
css代碼:
<style type="text/css">
.box1{width:300px;height:300px;background:pink;}
.box2{width:200px;height:200px;background:skyblue;}
.box3{width:100px;height:100px;background:gray;}
</style>複製代碼
html+js代碼:
<body> <div class="box1">
<div class="box2">
<div class="div box3"></div>
</div>
</div>
<script type="text/javascript">
//獲取對象
var box1 = document.getElementsByClassName('box1')[0];
var box2 = document.getElementsByClassName('box2')[0];
var box3 = document.getElementsByClassName('box3')[0];
//點擊事件
box1.addEventListener('click',function(){
console.log("捕獲 box1");
},true);
box2.addEventListener('click',function(){
console.log("捕獲 box2");
},true);
box3.addEventListener('click',function(){
console.log("捕獲 box3");
},true);
</script>
</body>複製代碼
動態效果以下:
當我點擊最裏面的 box3 時,咱們能夠看到最外層的事件先被觸發,最後纔是咱們點擊的 box3 事件被觸發,這即是事件捕獲。