DOM事件總結

DOM事件模型

dom事件模型分爲腳本模型,內聯模型和動態綁定三種。javascript

<html>
        <body>
            <!--行內綁定:腳本模型-->
            <div onclick="javascrpt:alert('eventType1')" id="eventType1">腳本模型</div>
            <!--內聯模型: 屢次聲明,只能綁定一次,後聲明,後生效-->
            <div onclick="sayType" id="eventType2">內聯模型</div>
            <!--動態綁定:能夠綁定屢次,均可生效-->
            <div id="eventType3">動態綁定</div>
        </body>
        
        <script> function sayType(){ alert('eventType2-1') } // 會覆蓋以前的事件聲明 document.getElementById('eventType2').onclick = function(){ alert('eventType2-2') } var eventType3Dom = document.getElementById('eventType3') eventType3Dom.onclick = function(){ alert('eventType3-1') } // 生效 eventType3Dom.addEventListener('click',function(){ alert('eventType3-2') }) // 生效 eventType3Dom.addEventListener('click',function(){ alert('eventType3-2') }) </script>
    </html>
複製代碼

DOM事件流

DOM結構是一個樹型結構,當一個HTML元素產生一個事件時,該事件會在元素結點與根結點之間的路徑傳播,路徑所通過的結點都會收到該事件,這個傳播過程可稱爲DOM事件流。DOM同時支持兩種事件模型:捕獲型事件和冒泡型事件。html

"DOM2事件流"規定的事件流包括三個階段:事件捕獲階段,處於目標階段,事件冒泡階段。java

DOM事件流圖示

事件捕獲階段

document對象首先接收到事件,而後事件沿着DOM樹依次向下,一直傳播到事件的實際目標。瀏覽器

事件捕獲的用意在於在事件到達預約目標以前就捕獲它。給addEventListener第三個參數傳入true便可監聽捕獲事件。app

<html>
        <body>
           <div id="div">div</div>
        </body>
        
        <script> document.getElementById('div').addEventListener('click',function(){ alert('div') },true) document.addEventListener('click',function(){ alert('html') },true) document.body.addEventListener('click',function(){ alert('body') },true) </script>
    </html>
複製代碼

依次打印html body divdom

事件捕獲階段

事件冒泡(event bubbling),即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,而後逐級向上傳播到較爲不具體的節點。函數

<html>
        <body>
           <div id="div">div</div>
        </body>
        
        <script> document.getElementById('div').addEventListener('click',function(){ alert('div') },true) document.addEventListener('click',function(){ alert('html') },true) document.body.addEventListener('click',function(){ alert('body') },true) </script>
    </html>
複製代碼

依次打印div body html性能

阻止冒泡

function stopBubble(e) { 
        //若是提供了事件對象,則這是一個非IE瀏覽器 
        if ( e && e.stopPropagation ) {
            //所以它支持W3C的stopPropagation()方法 
            e.stopPropagation(); 
        } else { 
            //不然,咱們須要使用IE的方式來取消事件冒泡 
            window.event.cancelBubble = true;
        } 
}
複製代碼

阻止默認行爲

function stopDefault( e ) { 
        //阻止默認瀏覽器動做(W3C) 
        if ( e && e.preventDefault ) {
            e.preventDefault(); 
        //IE中阻止函數器默認動做的方式 
        } else { 
            window.event.returnValue = false; 
        }
        return false; 
    }
複製代碼

DOM事件的一些優化方法

事件委託

事件委託就是利用事件冒泡,只指定一個事件處理程序,就能夠管理某一類型的全部事件。優化

<ul id="parent">
  <li class="child">one</li>
  <li class="child">two</li>
  <li class="child">three</li>
</ul>

<script> //父元素 var dom= document.getElementById('parent'); //父元素綁定事件,代理子元素的點擊事件 dom.onclick= function(event) { var event= event || window.event; var curTarget= event.target || event.srcElement; if (curTarget.tagName.toLowerCase() == 'li') { //事件處理 } } </script>
複製代碼

侷限性:ui

  • focus、blur 之類的事件自己沒有事件冒泡機制,因此沒法委託
  • mousemove、mouseout 這樣的事件,雖然有事件冒泡,可是隻能不斷經過位置去計算定位,對性能消耗高,不適合事件委託

節流函數解決頻繁回調的事件

規定在一個單位時間內,只能觸發一次函數。若是這個單位時間內觸發屢次函數,只有一次生效。

function throttle(fn,delay){
    var flag = true;
    var _this = this;
    
    return function(){
        if (flag === false) {
            return; 
        }
        
        flag = false;
        var args = arguments;
        
        setTimeout(function(){
            fn.apply(_this, args);
            flag = true;
        },delay || 500);
    }
}

// onsize事件
window.onresize = throttle(function (e) console.log(123); }, 500) 複製代碼

防抖函數解決連續觸發事件

在事件被觸發n秒後再執行回調,若是在這n秒內又被觸發,則從新計時。

<button id="button">連續點擊</button>

<script> function debounce (fn, delay){ var timer = null; var _this = this; return function(){ var args = arguments; clearTimeout(timer); timer = setTimeout(function(){ fn.apply(_this, args); },delay || 500); } } // 500ms只執行一次 document.getElementById('button').addEventListener('click',debounce(function(){ console.log(123) })) </script>
複製代碼
相關文章
相關標籤/搜索