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>
复制代码
相关文章
相关标签/搜索