zishu's blog

zishu's blog

一个热爱生活的博主。https://zishu.me

事件監聽函數,以及事件的捕獲和冒泡機制

事件一般是用於瀏覽器和用戶操作之間的互動,當用戶執行某些特殊的操作時,瀏覽器給予反應,觸發綁定的事件,事件流,事件發生時會在元素節點和根節點之間按照約定的順序傳播,事件經過的所有節點都會受到事件的影響,這個傳播過程被稱為 DOM 事件流

函數事件#

事件一般是用於瀏覽器和用戶操作之間的互動,當用戶執行某些特殊的操作時,瀏覽器給予反應,觸發綁定的事件

事件流,事件發生時會在元素節點和根節點之間按照約定的順序傳播,事件經過的所有節點都會受到事件的影響,這個傳播過程被稱為 DOM 事件流

image

true 是捕獲,false 是冒泡,默認為冒泡事件

1.addEventListener ()--添加事件監聽函數#

給元素添加一個事件,假如有多個事件,不會覆蓋,會依次執行

<div id="demo">dom</div>
<script>
    document.getElementById('demo').addEventListener("click", myfun)
    document.getElementById('demo').addEventListener("click", myfun1)

    function myfun() {
        console.log('事件監聽函數')
    }

    function myfun1() {
        console.log('addEventListener')
    }
</script>

image

注意:
1. 這裡有一個細節,addEventListener () 裡面有兩個參數,第一個表示觸發的條件,第二個表示觸發的事件
正常情況下,第二個參數直接寫函數名並且不加參數(),如果加了參數()則表示立即執行,不需要觸發第一個參數要求的條件

2. 在這裡綁定事件的時候,事件名不能和定義的變量名一樣,否則無效

2.removeEventListener ()--移除事件監聽函數#

下面這個 demo,當鼠標在 div 中移動的時候,出現隨機數,點擊按鈕後,移除事件監聽函數

<!-- css -->
<style>
    #demo {
        width: 100px;
        height: 100px;
        border: 1px solid #000;
    }
</style>

<!-- html -->
<div id="demo"></div>
<input type="button" value="點擊移除" onclick="remove()">
<div id="show"></div>

<!-- js -->
<script>
    document.getElementById('demo').addEventListener("mousemove", myfun)
    function myfun() {
        document.getElementById('show').innerHTML = Math.random()
    }

    function remove() {
        document.getElementById('demo').removeEventListener("mousemove", myfun)
    }
</script>

3. 利用事件的捕獲和冒泡做點事情#

addEventListener () 和 removeEventListener () 其實擁有三個參數,剛才說過了,第一個表示觸發條件,第二個表示觸發事件,第三個參數正常情況下可以省略,但是要知道它代表的意思

用布爾值來表示,true 或者 false,默認是 false

image

  • true 表示在捕獲階段調用事件處理程序
  • false 表示在冒泡階段調用事件處理程序

根據圖片可以看出,捕獲階段要先於冒泡階段,因此,true 事件要先於 flase 事件觸發,多個 true 事件按順序觸發,多個 false 事件,寫在後面的先觸發

結論:寫在前面的 true 事件 > 寫在後面的 true 事件 > 寫在後面的 false 事件 > 寫在前面的 false 事件

因此,利用這個參數,可以控制同一個元素的不同事件觸發的順序

<div id="out">
    <p>最外面</p>
    <div id="middle">
        <div id="inner">最裡面</div>
    </div>
</div>

<!-- 第一種情況 -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //點擊inner時,觸發順序為:inner-------middle------out
    out.addEventListener('click',function(){alert("我是最外面的");},false);   
    middle.addEventListener('click',function(){alert("我是中間的");},false);    
    inner.addEventListener('click',function(){alert("我是最裡面的");},false); 
</script>

<!-- 第二種情況 -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //點擊inner時,觸發順序為:out------middle-------inner
    out.addEventListener('click',function(){alert("我是最外面的");},true);   
    middle.addEventListener('click',function(){alert("我是中間的");},true);  
    inner.addEventListener('click',function(){alert("我是最裡面的");},true); 
</script>

<!-- 第三種情況 -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //點擊inner時,觸發順序為:out------inner-------middle
    out.addEventListener('click',function(){alert("我是最外面的");},true);   
    middle.addEventListener('click',function(){alert("我是中間的");},false);    
    inner.addEventListener('click',function(){alert("我是最裡面的");},false);
</script>

<!-- 第四種情況 -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //點擊inner時,觸發順序為:out-------middle------inner
    out.addEventListener('click',function(){alert("我是最外面的");},true);   
    middle.addEventListener('click',function(){alert("我是中間的");},true);  
    inner.addEventListener('click',function(){alert("我是最裡面的");},false);
</script>

<!-- 第五種情況 -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //點擊inner時,觸發順序為:middle-------inner------out
    out.addEventListener('click',function(){alert("我是最外面的");},false);   
    middle.addEventListener('click',function(){alert("我是中間的");},true);  
    inner.addEventListener('click',function(){alert("我是最裡面的");},false);
</script>

<!-- 第六種情況 -->
<script>
    var out = document.getElementById('out'); 
    var middle = document.getElementById('middle'); 
    var inner = document.getElementById('inner'); 
    //點擊inner時,觸發順序為:out-------inner------middle
    out.addEventListener('click',function(){alert("我是最外面的");},true);   
    middle.addEventListener('click',function(){alert("我是中間的");},false);    
    inner.addEventListener('click',function(){alert("我是最裡面的");},true);
</script>

4. 事件處理程序#

  1. HTML 事件處理程序
<button onclick="test()">測試</button>
<script>
    function test() {
        alert("HTML事件處理程序");
    }
</script>

1. 優點:事件處理程序中的代碼,能夠訪問全局作用域中的任何變量
2. 缺點:時差問題、擴展的作用域鏈在不同瀏覽器中會導致不同結果、html 代碼與 js 代碼高度耦合

  1. DOM0 級事件處理程序
<button id="btn">測試</button>
<script>
    var btn = document.getElementById("btn");
    btn.onclick = function test() {
        alert("DOM0級事件處理程序");
    }
</script>

1. 優點:代碼簡單,瀏覽器兼容性好,解決了 html 代碼和 js 代碼的高度耦合問題
2. 缺點:一個元素只能綁定一個事件處理函數,只會在事件冒泡中運行

  1. DOM2 級事件處理程序

該級別的事件處理程序,運用的就是事件捕獲和冒泡機制

<button id="btn">測試</button>
<script>
    var btn = document.getElementById("btn");

    // 事件監聽
    btn.addEventListener("click", function() {
        alert("DOM2級事件處理程序,我在捕獲階段執行");
    }, true);

    btn.addEventListener("click", function() {
        alert("DOM2級事件處理程序,我在冒泡階段執行");
    }, false);

    // 移除事件監聽
    var fun = function() {
        alert("我要被移除了");
    }
    btn.addEventListener("click", fun, false);
    btn.removeEventListener("click", fun, false);
</script>

1. 優點:同時支持事件處理的捕獲和冒泡階段,並且一個元素可以綁定多個處理函數
2. 缺點:IE 不支持

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。