第19课——事件冒泡和事件委托

事件冒泡和捕获

```css
<style>
    .out {
        width: 300px;
        height: 300px;
        background-color: cadetblue;
    }
    .center {
        width: 200px;
        height: 200px;
        background-color:burlywood;
    }
    .inner {
        width: 100px;
        height: 100px;
        background-color: blueviolet;
    }
</style>
```
```html
<div class="out">
    <div class="center">
        <div class="inner">

        </div>
    </div>
</div>
```
```js
    var outEle = document.querySelector(".out");
    var centerEle = document.querySelector(".center");
    var innerEle = document.querySelector(".inner");
    window.addEventListener("click",function(){
        console.log("window");
    });
    document.documentElement.addEventListener("click",function(){
        console.log("HTML");
    });
    document.body.addEventListener("click",function(){
        console.log("body");
    });
    outEle.addEventListener("click",function(){
        console.log("out");
    });
    centerEle.addEventListener("click",function(){
        console.log("center");
    });
    innerEle.addEventListener("click",function(){
        console.log("inner");
    });
```
    当说起事件冒泡时,首先我们先看一下上述代码,当我们点击最里层元素innerEle时,我们同时点了包含它
    的所有父级元素和祖先元素,但是我们发现它执行的顺序却是从最小范围的元素开始向上执行。
事件冒泡机制:
    从内向外,从小到大,依次触发事件执行。

事件冒泡捕获:
    通过addEventListener的第三个参数控制的,默认值是false冒泡,true为捕获。当元素被捕获时,冒泡机制
    就不在使用被捕获的元素,被捕获的元素会按照注册/调用的顺序执行,然后再就是执行冒泡机制
例:将上述js代码改成以下,我们将outEle元素捕获
 var outEle = document.querySelector(".out");
     var centerEle = document.querySelector(".center");
     var innerEle = document.querySelector(".inner");
     window.addEventListener("click",function(){
         console.log("window");
     });
     document.documentElement.addEventListener("click",function(){
         console.log("HTML");
     });
     document.body.addEventListener("click",function(){
         console.log("body");
     });
     outEle.addEventListener("click",function(){
         console.log("out");
     },true);
     centerEle.addEventListener("click",function(){
         console.log("center");
     });
     innerEle.addEventListener("click",function(){
         console.log("inner");
     });
最后执行的结果为,out,inner,center,body,HTML,window
阻止事件冒泡
两种方式     1.ele.stopPropagation();
            2.ele.cancelBubble = true ;
触发目标
<ul>
  <li>111</li>
  <span>222</span>
  <p>333</p>
</ul>
var ulEle = document.querySelector("ul");
ulEle.addEventListener("click",function( event ){
      var e = event || window.event ; 
      console.log(e.target);
});

当我们用对象事件中键名为target时,会发现我们点击那个子元素,target就会指向哪个子元素,
这时候target可以表示我们的靶元素或者目标元素
–注--
target的兼容性,在谷歌浏览器中,用target表示目标元素/靶元素
在ie8及以下浏览器中,用srcElement表示目标元素/靶元素
我们可以用 var target = e.target || e.srcElement ; 表示兼容

事件委托


事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown......)的函数委托到另一个元素;

一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当
事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素
上去执行函数。
举个例子,比如一个宿舍的同学同时快递到了,一种方法就是他们都傻傻地一个个去领取,还有一种方法就是
把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一一分发给每个宿舍同学;
在这里,取快递就是一个事件,每个同学指的是需要响应事件的 DOM 元素,而出去统一领取快递的宿舍长就是
代理的元素,所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响
应的事件应该匹配到被代理元素中的哪一个或者哪几个。

---- / 引用知乎作者 :桐城 /

前面我们学过冒泡以及用e.target表示靶元素/目标元素,当我们在多层循环中多次绑定相似的元素时,可以用target
来表示绑定DOM操作的元素,直接用target来操作该元素

例:

   <ul>
       <span>2222</span>
       <li>1111</li>
       <li>1111</li>
       <li>1111</li>
   </ul>
   var ulEle = document.querySelector("ul");
   ulEle.onclick = function (){
       var e = event || window.event ; 
       var target = e.target || e.srcElement ; 
       if ( target.nodeName == "LI" ){
           target.innerHTML = "3333" ;
       }
   }
    当我们需要改变li里面内容变成3333时,如果用传统的绑定:
        1、我们需要先获取li元素组成的伪数组
        2、给伪数组遍历每一个li元素并绑定点击事件
        3、修改li元素里的文本内容
    当我们用事件委托:
        1、获取它的父级元素并绑定事件
        2、判断target元素是否我我们鼠标点击的元素
        3、修改target元素中的文本内容

可以看出,事件委托有以下优点:
a.性能更好。事件委托减少了循环
b.在动态修改元素这块,事件委托修改元素不会受到影响
c.减少了元素的事件绑定的操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值