1. 程式人生 > >JavaScript 事件機制

JavaScript 事件機制

param ons 先後 case 數據 dde tlist 如果 tolower

事件流是一個事件沿著特定數據結構傳播的過程。冒泡和捕獲是事件流在DOM中兩種不同的傳播方法。
事件流有三個階段:

  1. 事件捕獲階段
  2. 處於目標階段
  3. 事件冒泡階段

什麽是捕獲和冒泡

假設有節點如下:

    <div id="div1">
        <div id="div2"></div>
    </div>
    
    <script>
        let div1 = document.getElementById(‘div1‘);
        let div2 = document.getElementById(‘div2‘);
        
        div1.onClick = function(){
            alert(‘1‘)
        }
        
        div2.onClick = function(){
            alert(‘2‘);
        }
    
    </script>

當點擊 div2時,會彈出兩個彈出框。在 ie8/9/10、chrome瀏覽器,會先彈出"2"再彈出“1”,這就是事件冒泡:事件從最底層的節點向上冒泡傳播。事件捕獲則跟事件冒泡相反。
W3C的標準是先捕獲再冒泡addEventListener的第三個參數決定把事件註冊在捕獲(true)還是冒泡(false)

事件綁定

在各種瀏覽器中綁定事件有不同的寫法。

傳統的事件綁定:在元素上使用 onClick綁定
它可以適應不同的瀏覽器,但是只能在事件冒泡中運行(捕獲不行),一次只能綁定一個。

    var ele = document.getElementById(‘xDiv‘);
    ele.onClick  =  function(e){
        console.log(‘指向當前的this‘,this);
        console.log(e.currentTarget);
    }
    

w3c事件綁定:使用addEventListener()函數
這種綁定支持冒泡捕捉,同時可以對一個元素進行多次綁定,按書寫先後順序執行。

var ele = document.getElement(‘xDiv‘);

// 最後一個參數表示事件的處理階段,true是捕獲,false是冒泡
ele.addEventListener(‘click‘,(e)=>{
    console.log(e);
},true);

但是IE9以下不支持 addEventListener函數,IE瀏覽器要使用 attachEvent函數代替。

IE的事件綁定attachEvent函數支持全系列IE,但是其他瀏覽器不支持。

    var ele = document.getElementById(‘xDiv‘);
    
    ele.attachEvent(‘onclick‘,()=>{
        console.log(‘指向全局的this‘,this);
    });
    

attachEvent支持事件捕捉階段,不支持冒泡階段。
另外需要註意的是 attachEvent的執行順序是從後往前

兼容寫法
如果我們要兼容多個瀏覽器的事件綁定,則可以這樣寫

    if(window.addEventListener){
        //chrom firefor ...
        object.addEventListener(‘click‘,function(){
        },false);
    }
    else if(window.attachEvent){
        //IE
        object.attachEvent(‘onclick‘,function(){})
    }
    else{
        object.onclick = function(){}
    }

事件流阻止

在一些情況下需要阻止事件流的傳播,阻止默認動作的發生。

event.preventDefault():取消事件對象的默認動作以及繼續傳播。
event.stopPropagation()/ event.cancelBubble = true:阻止事件冒泡。

事件的阻止在不同瀏覽器有不同處理

  • 在IE下使用 event.returnValue= false
  • 在非IE下則使用 event.preventDefault()進行阻止。

preventDefaultstopPropagation的區別

  • preventDefault告訴瀏覽器不用執行與事件相關聯的默認動作(如表單提交)
  • stopPropagation是停止事件繼續冒泡,但是對IE9以下的瀏覽器無效

事件委托

在js中性能優化的其中一個主要思想是減少dom操作
假設有100個li,每個li有相同的點擊事件。如果為每個Li都添加事件,則會造成dom訪問次數過多,引起瀏覽器重繪與重排的次數過多,性能則會降低。
使用事件委托則可以解決這樣的問題。

原理

實現事件委托是利用了事件的冒泡原理實現的。當我們為最外層的節點添加點擊事件,那麽裏面的ul、li、a的點擊事件都會冒泡到最外層節點上,委托它代為執行事件。

實現

    <ul id="ul">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    
    window.onload = function(){
        var ulEle = document.getElementById(‘ul‘);
        ul.onclick = function(ev){
            //兼容IE
            ev = ev || window.event;
            var target = ev.target || ev.srcElement;
            
            if(target.nodeName.toLowerCase() == ‘li‘){
                alert( target.innerHTML);
            }
            
        }
    }
    


作者:Guanmac
鏈接:https://www.jianshu.com/p/916230ad9229
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。

JavaScript 事件機制