事件冒泡及捕获

浏览器处理DOM事件的过程

谈之前,先说以一下三种常见的事件绑定方法:

  • 在DOM元素中直接绑定<input type="button" value="click me" onclick="hello()"/>

  • 在javascript代码中绑定<input type="button" value="click me" id="btn"/>

    <script type="text/javascript">

    ​ document.getElementById(“btn”).onclick = function()

    ​ {

    ​ alert(“hello”);

    ​ };

  • 绑定事件监听函数 通过addEventListener() 或 attachEvent()来绑定事件监听函数。

事件监听

对于事件的捕获和处理,不同的浏览器厂商有哦不同的处理机制,这里介绍W3C对DOM2.0定义的标准事件。

DOM2.0模型将事件处理流程分为三个阶段:一. 事件捕获阶段 二.事件目标阶段,三. 事件冒泡阶段。

事件阶段:

当一个DOM事件被触发的时候,他并不是只在它的起源对象上触发一次,而是会经历三个不同的阶段。简而言之:事件一开始从文档的根节点流向目标对象(捕获阶段),然后在目标对向上被触发(目标阶段),之后再回溯到文档的根节点(冒泡阶段)。

addEventListener(eventName , callback , false/true);

false:表示在事件冒泡阶段添加监听回调函数;

true:表示在事件捕获阶段添加监听回调函数;

图片

一般在实际应用中,我们并没有太多使用捕获阶段监听的用例,即一般 采用false在事件冒泡阶段添加监听回调函数。

  • 事件捕获:当某个元素触发某个事件,顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

  • 事件目标:当事件流到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。

    ​ 对于多层嵌套的节点,鼠标和指针事件经常会被定位到最里层的元素上。

    ​ 假设,你在一个div元素上设置了click监听函数,而用户点击在了这个div

    ​ 元素内部的p元素上,那么p元素就是这个事件的目标元素。事件冒泡让我

    ​ 们可以在这个div或者更上层的元素上监听click事件,并且事件传播过程中

    ​ 触发监听回调函数。

  • 事件冒泡:事件在目标事件上触发后,并不在这个元素上终止,它会从目标元素开始,往顶层元素冒泡传播,直到到达最外层的根节点。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。如果想阻止事件冒泡,可以使用e.stopPropagation() 来阻止事件的冒泡传播。

事件委托

事件委托就是利用事件冒泡的原理,把事件添加到父元素或者祖先元素上,触发执行效果。

//传统写法

<ul id="list">
  <li id="item1" >item1</li>
  <li id="item2" >item2</li>
  <li id="item3" >item3</li>
</ul>

<script>
var list = document.getElementById("list");

var item = list.getElementsByTagName("li");
for(var i=0;i<item.length;i++){
  (function(i){
    item[i].onclick = function(){
      alert(item[i].innerHTML);
    }
  })(i)
}

var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);

</script>
/*-----点击item1到item3都有事件响应,但是点击item4时,没有事件响应。说明传统的事件绑定无法对动态添加的元素而动态的添加事件。-----*/
//使用事件委托

<ul id="list">
  <li id="item1" >item1</li>
  <li id="item2" >item2</li>
  <li id="item3" >item3</li>
</ul>

<script>
var list = document.getElementById("list");

document.addEventListener("click",function(event){
  var target = event.target;
  if(target.nodeName == "LI"){
    alert(target.innerHTML);
  }
})

var node=document.createElement("li");
var textnode=document.createTextNode("item4");
node.appendChild(textnode);
list.appendChild(node);

</script>
/*-----当点击item4时,item4有事件响应。说明事件委托可以为新添加的DOM元素动态的添加事件。-----*/

事件委托的优点

  1. 提高javascript性能。事件委托可以显著的提高时间的处理速度,减少内存的占用。
  2. 动态的添加DOM元素时,不需要因为元素的改动而修改事件绑定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值