JavaScript事件流
事件
事件是文档或者浏览器窗口中发生的,特定的交互瞬间
事件是用户或浏览器自身执行的某种动作,如click,load,mouseover都是事件的名字
事件是JavaScript和DOM之间交互的桥梁
你若触发,我便执行 – 事件发生 ,调用他的处理函数执行相应的JavaScript代码给出响应
典型的粒子有: 页面加载完毕触发load事件,用户单机元素,触发click事件
事件流
事件流描述的是从页面中接收事件的顺序
事件流的感性认识
问: 单机页面元素,都有什么元素可以感受到这样一个事件
答案: 单机元素的同时也单机了元素的容器元素(父元素,组辈元素),甚至整个页面
例子:
三个div嵌套 给每个div添加对应的事件处理程序(click)弹出对应的文字
单机最里面的div ,也同时单机了外面的圆(因为外面的圆包裹类名的圆),所以外面的两个div的click事件也会被触发
事件流
事件发生时会在元素节点与根节点之间按照特定的顺序传播,传播路径 所有经过的节点都会收到该事件, 这个传播的过程即是DOM事件流
两种事件流模型
事件传播的顺序对应浏览器的两种事件流模型: 捕获型事件流和冒泡型事件流
冒泡型事件流
事件的传播是从最特定的事件目标到最不特定的事件目标
即 从DOM 树的叶子 到 根 (从小到大)
捕获型事件流
事件的传播是从最不特定的事件目标到最特定的事件目标、
即 从 DOM 树的 根 到叶子 (从大到小)
事件捕获的思想就是 不太具体的节点应该更早接收到事件,而最具体的节点 最后收到事件
示例
假如在body中 写了一个div’元素
点击了该div
在冒泡型事件流中click事件传播顺序为
在捕获型事件流中click事件传播顺序为document—》—》—》
// 所有的现代浏览器都支持事件冒泡 但在具体实现中略有差别
具体的区别请看原创文章
https://www.cnblogs.com/starof/p/4066381.html
DOM事件流
DOM标准采用捕获+冒泡。两种事件流都会触发DOM的所有对象,从document对象开始,也在document对象结束。
DOM标准规定事件流包括三个阶段
DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
事件捕获阶段:实际目标(
处于目标阶段:事件在
冒泡阶段:事件又传播回文档。
注
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