JS中的事件传播流程

一 事件基础

JavaScript 事件是由访问 Web 页面的用户引起的一系列操作。
当用户执行某些操作的时候,再去执行一系列代码。或者用来获取事件的详细信息,
如鼠标位置、键盘按键等。

二 事件流

事件流描述的是页面接收事件的顺序。
事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流。

事件流的三个阶段

1.捕获阶段:事件对象从目标的祖先节点Window开始传播直至目标。
2.目标阶段:事件对象传递到事件目标。如果事件的type属性表明后面不会进行冒泡操作,那么事件到此就结束了。
3.冒泡阶段:事件对象以一个相反的方向进行传递,从目标开始,到Window对象结束。

事件的冒泡

事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。

事件的捕获

事件按照从最不特定的事件目标到最特定的事件目标(document对象)的顺序。
下面是一个实例

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            #outer{
                width: 200px;
                height: 200px;
                background: red;
            }
            #inner{
                width: 100px;
                height: 100px;
                background: blue;
            }
        </style>
    </head>
    <body>
        <div id="outer">
            <div id="inner"></div>
        </div>
        <script type="text/javascript">
            var outer = document.getElementById("outer");
            var inner = document.getElementById("inner");
            document.onclick = function(){
                console.log("document");
            }
            inner.onclick = function(e){
                var evt = e || event;
                console.log("inner");
            }
            outer.onclick = function(e){
                var evt = e || event;
                console.log("outer");
            }
        </script>
    </body>
</html>

当点击最外面的白色部分时,只触发document.onclick,控制台输出document。
当点击红色部分时,触发outer.onclick,同时冒泡到document对象上,所以控制台输出outer和document。
当点击蓝色部分时,触发inner.onclick,同时冒泡到outer和document对象上,所以控制台输出inner,outer,document。

三 阻止事件冒泡

不同浏览器对阻止冒泡的写法存在兼容问题,在ie浏览器中阻止冒泡的方法是window.event.cancelBubble=true而在谷歌,火狐等浏览器的方法则是e.stopPropagation()
阻止事件在DOM中继续传播,即取消进一步的事件捕获或冒泡,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数。

outer.onclick = function(e){
    var evt = e || event;
    console.log("outer");
    if(evt.stopPropagation){
        evt.stopPropagation();
    }else{
        evt.cancelBubble = true;
    }
}

四 事件委托

利用事件冒泡的特性,将里层的事件委托给外层事件,根据event对象的属性进行事件委托,改善性能。
使用事件委托能够避免对特定的每个节点添加事件监听器;事件监听器是被添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到是哪个子元素的事件。
举个例子,点击更多添加li,且点击每个li都输出aa,点击其他地方不显示。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            li{
                background: red;
                margin: 10px;
            }
        </style>
    </head>
    <body>
        <ul id="list">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
        <input type="button" value="更多" id="btn">
        <script type="text/javascript">
            var oList = document.getElementById("list");
            var oBtn = document.getElementById("btn");
            var aLi = oList.children;
            oList.onclick = function(e){
                var evt = e || event;
                var _target = evt.target || evt.srcElement;
                if(_target.nodeName.toLowerCase() == "li"){
                    console.log("aa");
                }
            }
            oBtn.onclick = function(){
                for(var i = 0; i < 5; i++){
                    var oLi = document.createElement("li");
                    oList.appendChild(oLi);
                }
            }
        </script>
    </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值