js事件传播流程

事件的默认传播机制:

JS里事件传播流程

Javascript与HTML之间的交互是通过事件实现的。
事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
可以使用侦听器来预定事件,以便事件发生时执行相应代码。

事件流

JS事件流最早要从IE和网景公司的浏览器大战说起,IE提出的是冒泡流,而网景提出的是捕获流,后来在W3C组织的统一之下,JS支持了冒泡流和捕获流,但是目前低版本的IE浏览器还是只能支持冒泡流(IE6,IE7,IE8均只支持冒泡流),所以为了能够兼容更多的浏览器,建议大家使用冒泡流。

事件流原理图如下:
在这里插入图片描述
从图中我们可以知道

1、一个完整的JS事件流是从window开始,最后回到window的一个过程

2、事件流被分为三个阶段(1-5)捕获过程、(5-6)目标过程、(6-10)冒泡过程

3、在冒泡过程中6比7早触发。

事件传播的三个阶段

第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。

这种三阶段的传播模型,会使得一个事件在多个节点上触发。比如,假设div节点之中嵌套一个p节点。
捕获阶段:从外向里依次查找元素
目标阶段:从当前事件源本身的操作
冒泡阶段:从内到外依次触发相关的行为(我们最常用的就是冒泡阶段)
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    #outer{
      margin:20px auto;
      padding:20px;
      width:300px;
      height:300px;
      background:#008000;
    }
    #inner{
      padding:20px;
      width:200px;
      height:200px;
      background:blue;
    }
    #center{
      padding:20px;
      width:100px;
      height:100px;
      background:yellow;
    }
  </style>
</head>
<body>
  <div id='outer'>
    <div id='inner'>
      <div id='center'></div>
    </div>
  </div>
  <script>
    var outer = document.getElementById('outer'),inner = document.getElementById('inner'),center = document.getElementById('center');
    //使用DOM0级事件绑定给元素的某一个行为绑定的方法,都是在行为触发后的冒泡阶段把方法执行的
    document.body.onclick = function(){
      console.log('body')
    }
    outer.onclick = function(){
      console.log('outer')
    }
    inner.onclick = function(){
      console.log('inner')
    }
    center.onclick = function(){
      console.log('center')
    }
 
    //addEventListener 第一个参数是行为的类型 第二个参数是给当前的行为定义的方法 第三个参数是控制在哪个阶段发生:true 在捕获阶段发生 false在冒泡阶段发生
    document.body.addEventListener('click',function(){
      console.log('body')
    },false)
    outer.addEventListener('click',function(){
      console.log('outer')
    },true)
    inner.addEventListener('click',function(){
      console.log('inner')
    },false)
 
    //输出 outer inner body
  </script>
</body>
</html>

在这里插入图片描述

event.stopPropagation()

stopPropagation方法阻止事件在DOM中继续传播,即取消进一步的事件捕获或冒泡,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数。
我们可以在button的事件处理程序中调用stopPropagation()从而避免注册在body上的事件发生。

var handler = function(e){
    alert(e.type);
    e.stopPropagation();
}
addEvent(document.body, 'click', function(){alert('Clicked body')});
var btnClick = document.getElementById('btnClick');
addEvent(btnClick, 'click', handler);

//若是注释掉e.stopPropagation();在点击button的时候,由于事件冒泡,body的click事件也会触发,但是调用后这句后,事件会停止传播。

event.preventDefault()

preventDafault方法取消浏览器对当前事件的默认行为,比如点击链接后,浏览器跳转到指定页面,或者按一下空格键,页面向下滚动一段距离。该方法生效的前提是,事件的cancelable属性为true如果为fales,则调用该方法没有任何效果。
该方法不会阻止事件的进一步传播(stopPropagation方法可用于这个目的)。只要在事件的传播过程中使用了preventDefault方法,该事件的默认方法就不会执行。

//html代码为
//<input type="checkbox" id="my-checkbox"/>

var cb = document.getElementById('my-checkbox');
cb.addEventListener('click', function(e){
    e.preventDafault();
},);

上面代码为点击单选框事件,设置监听函数,取消默认行为。由于浏览器的默认行为是选中单选框,所以这段代码会导致无法选中单选框。
利用这个方法,可以为文本输入框设置校验条件。如果用户的输入不符合条件,就无法将字符输入文本框。

function checkName(e){
    if(e.charCode < 97 || e.charCode > 122){
        e.preventDafault();
    }
}

//keypress监听函数,只能输入小写字母,否则输入事件的默认事件(写入文本框)将本取消。
如果监听函数最后返回布尔值false(return false),浏览器也不会触发默认行为,与preventDafault方法有等同效果。

事件代理

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理
定义:事件代理就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。(delegation)。

var ul = document.querySelector('ul');
ul.addEventListener('click', function(event){
    if(event.target.tagName.toLowerCase() === 'li'){
        //...
    }
})

上面代码的click事件的监听函数定义在<ul>节点,但是实际上,它处理的是子节点<li>的click事件。这样的好处是,只要定义一个监听函数,就能处理多个子节点的事件,且以后再添加子节点,监听函数依然有效。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值