JS之事件流(事件冒泡和事件捕获),阻止事件冒泡的方法,事件委托

一、事件流

1、什么是事件流?

事件流描述的是从页面中接受事件的顺序。
但有意思的是,微软(IE)和网景(Netscape)开发团队居然提出了两个截然相反的事件流概念,IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕获流(event capturing)。
后来在W3C组织的统一之下,JS支持了冒泡流和捕获流,但是目前低版本的IE浏览器还是只能支持冒泡流(IE6,IE7,IE8均只支持冒泡流),所以为了能够兼容更多的浏览器,建议大家使用冒泡流。
事件流包含的三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
接下来就是介绍这两种事件流概念

2、事件捕获

事件捕获流的思想是不太具体的DOM节点应该更早接收到事件,而最具体的节点应该最后接收到事件
简单来说就是从父元素到子元素传播,从外向内
实现事件捕获的方式:

addEventListener(type,listener,useCapture); //第三个参数表示是否支持事件捕获
// 事件捕获 --- 从外向内
        oDiv.addEventListener( 'click' , function () {  
            console.log('我是最外面的');
        } , true)

        oP.addEventListener( 'click' , function () {  
            console.log('我是中间的');
        } , true)

        oSpan.addEventListener( 'click' , function () {  
            console.log('我是最里面的');
        } , true)

3、事件冒泡

IE提出的事件流叫做事件冒泡,即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点

在这里插入图片描述
简单来说就是从子元素到父元素传播,从内向外

// 默认是事件冒泡 --- 从里向外
		oDiv.addEventListener( 'click' , function () {  
            console.log('我是最外面的');
        })

        oP.addEventListener( 'click' , function () {  
            console.log('我是中间的');
        })

        oSpan.addEventListener( 'click' , function () {  
            console.log('我是最里面的');
        })

二、阻止事件冒泡

在实际的项目中,我们一般需要阻止事件冒泡
阻止事件冒泡:

要利用到事件对象:
      e.stopPropagation()
      e.cancelBubble = true
<body>
    <div class="a">
        <p>
            <span></span>
        </p>
    </div>
    <script>
        var oDiv = document.querySelector('.a')
        var oP = document.querySelector('p') ;
        var oSpan = document.querySelector('span')

        oDiv.onclick = function () {  
            console.log('div');
        }

        oP.onclick = function (e) {  
            e = e || event ;
            // 阻止事件冒泡
            // 主流浏览器的写法
            e.stopPropagation()
            // 低版本IE取消事件冒泡的方法
            e.cancelBubble = true ;
            if(e.stopPropagation) {
                e.stopPropagation()
            } else {
                e.cancelBubble = true ;
            }
            console.log('p');
        }      
       
    </script>
    
</body>

三、事件委托

栗子:

	<ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>10</li>
    </ul>

如果页面上的事件处理函数过多则会对性能造成影响,如果需要让每个li都有点击事件,循环绑定事件 — 页面上实际会有很多的事件处理函数。并且循环绑定事件无法给将来的对象绑定事件。
解决方案:事件委托

事件委托的实现:
利用事件冒泡,子元素的事件都会触发父元素的事件
找到所有需要绑定事件的父元素,给父元素绑定事件,然后根据target来判断具体是由谁触发的

		var oLis = document.querySelectorAll('li') ;
        var oUl = document.querySelector('ul')

        setTimeout(function () {  
            var fragment = document.createDocumentFragment() ; //创建文档碎片
            for(var i = 11 ; i < 21 ; i++) {
                var oLi = document.createElement('li') ;
                oLi.innerHTML = i ;
                fragment.appendChild(oLi) //将子元素都添加到文档碎片中
            }
            oUl.appendChild(fragment) //一次性将所有子元素添加到父元素中
        },1000)

		oUl.onclick = function (e) {  
            console.log(e.target.innerHTML); //点击触发
        }
事件委托小结

概念:子元素的同类型事件委托给父元素来实现
优点: 1.减少事件处理函数优化页面性能
            2.可以给将来的对象绑定事件
原理:事件冒泡 — 子元素的同类型事件都会触发父元素的同类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值