JavaScript事件流

事件

事件是文档或者浏览器窗口中发生的,特定的交互瞬间
事件是用户或浏览器自身执行的某种动作,如click,load,mouseover都是事件的名字
事件是JavaScript和DOM之间交互的桥梁
你若触发,我便执行 – 事件发生 ,调用他的处理函数执行相应的JavaScript代码给出响应
典型的粒子有: 页面加载完毕触发load事件,用户单机元素,触发click事件

事件流

事件流描述的是从页面中接收事件的顺序

事件流的感性认识

问: 单机页面元素,都有什么元素可以感受到这样一个事件
答案: 单机元素的同时也单机了元素的容器元素(父元素,组辈元素),甚至整个页面
例子:
三个div嵌套 给每个div添加对应的事件处理程序(click)弹出对应的文字
单机最里面的div ,也同时单机了外面的圆(因为外面的圆包裹类名的圆),所以外面的两个div的click事件也会被触发

事件流

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

两种事件流模型

事件传播的顺序对应浏览器的两种事件流模型: 捕获型事件流和冒泡型事件流

冒泡型事件流

事件的传播是从最特定的事件目标到最不特定的事件目标
即 从DOM 树的叶子 到 根 (从小到大)

捕获型事件流

事件的传播是从最不特定的事件目标到最特定的事件目标、
即 从 DOM 树的 根 到叶子 (从大到小)
事件捕获的思想就是 不太具体的节点应该更早接收到事件,而最具体的节点 最后收到事件
示例
假如在body中 写了一个div’元素
点击了该div
在冒泡型事件流中click事件传播顺序为

—》—》—》document

在捕获型事件流中click事件传播顺序为document—》—》—》


// 所有的现代浏览器都支持事件冒泡 但在具体实现中略有差别
具体的区别请看原创文章
https://www.cnblogs.com/starof/p/4066381.html

DOM事件流

DOM标准采用捕获+冒泡。两种事件流都会触发DOM的所有对象,从document对象开始,也在document对象结束。

DOM标准规定事件流包括三个阶段

DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

事件捕获阶段:实际目标(

)在捕获阶段不会接收事件。也就是在捕获阶段,事件从document到再到就停止了。上图中为1~3.
处于目标阶段:事件在
上发生并处理。但是事件处理会被看成是冒泡阶段的一部分。
冒泡阶段:事件又传播回文档。

1)、尽管“DOM2级事件”标准规范明确规定事件捕获阶段不会涉及事件目标,但是在IE9、Safari、Chrome、Firefox和Opera9.5及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两次机会在目标对象上面操作事件。

2)、并非所有的事件都会经过冒泡阶段 。所有的事件都要经过捕获阶段和处于目标阶段,但是有些事件会跳过冒泡阶段:如,获得输入焦点的focus事件和失去输入焦点的blur事件。
两次机会在目标对象上面操作事件的例子
https://www.cnblogs.com/starof/p/4066381.html 原创文章中

元素.addEventListener(事件名,回调函数,useCapture) 用户捕捉

此方法第三个参数传入 true代表捕获阶段触发
传入 false 代表冒泡阶段触发
默认就是false
若是L0 事件 监听 则只有冒泡阶段 没有捕获阶段

事件流的典型应用事件代理

传统的事件处理中,需要为每个元素添加事件处理器。js事件代理则是一种简单有效的技巧,通过它可以把事件处理器添加到一个父级元素上,从而避免把事件处理器添加到多个子级元素上。

1、事件代理

事件代理的原理用到的就是事件冒泡和目标元素,把事件处理器添加到父元素,等待子元素事件冒泡,并且父元素能够通过target(IE为srcElement)判断是哪个子元素,从而做相应处理。关于target更多内容请参考javaScript事件(四)event的公共成员(属性和方法) 下面举例来说明。
传统事件处理,为每个元素添加事件处理器,代码如下:

<body>
<ul id="color-list">
<li>red</li>
<li>orange</li>
<li>yellow</li>
<li>green</li>
<li>blue</li>
<li>indigo</li>
<li>purple</li>
</ul>
<script>
(function(){
    var colorList=document.getElementById("color-list");
    var colors=colorList.getElementsByTagName("li");
    for(var i=0;i<colors.length;i++)
    {
        colors[i].addEventListener('click',showColor,false);
    };
    function showColor(e)
    {
        e=e||window.event;
        var targetElement=e.target||e.srcElement;
        alert(targetElement.innerHTML);
    }
})();
</script>
</body>

事件代理的处理方式,代码如下:

<body>
<ul id="color-list">
<li>red</li>
<li>orange</li>
<li>yellow</li>
<li>green</li>
<li>blue</li>
<li>indigo</li>
<li>purple</li>
</ul>
<script>
(function(){
    var colorList=document.getElementById("color-list");
    colorList.addEventListener('click',showColor,false);
    function showColor(e)
    {
        e=e||window.event;
        var targetElement=e.target||e.srcElement;
        if(targetElement.nodeName.toLowerCase()==="li"){
        alert(targetElement.innerHTML);
        }
    }
})();
</script>
</body>

2、事件代理的好处

总结一下事件代理的好处:

将多个事件处理器减少到一个,因为事件处理器要驻留内存,这样就提高了性能。想象如果有一个100行的表格,对比传统的为每个单元格绑定事件处理器的方式和事件代理(即table上添加一个事件处理器),不难得出结论,事件代理确实避免了一些潜在的风险,提高了性能。
DOM更新无需重新绑定事件处理器,因为事件代理对不同子元素可采用不同处理方法。如果新增其他子元素(a,span,div等),直接修改事件代理的事件处理函数即可,不需要重新绑定处理器,不需要再次循环遍历。

3、事件代理的问题:

https://www.cnblogs.com/starof/p/4066381.html
参考这个文章吧

转载自:https://www.cnblogs.com/starof/p/4067121.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值