Js事件流

CONTENTS
  • DOM事件流
  • 事件冒泡
  • 阻止冒泡
  • 事件捕獲


DOM事件流

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>
複製代碼

當咱們點擊按鈕button時,事件時這樣傳播的:

(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 事件被觸發,這即是事件捕獲。 

相關文章
相關標籤/搜索