javascript 事件传播与事件冒泡,W3C事件模型
说实话笔者在才工作的时候就听说了什么"事件冒泡",弄了很久才弄个大概,当时理解意思是子级dom元素和父级dom元素都绑定了相同类型的事件,这时如果子级事件触发了父级也会触发,然后这就叫做"事件冒泡"。然而,事情要是这么简单的话,相信笔者这时一定已经迎娶了白富美,当上了CEO。坏就坏在后来又听说一个"事件传播" ,尼玛不是"事件冒泡"吗,然后又听说了"W3C事件模型"。。。到了最后笔者彻底心碎了,只能乖乖的当忙农了!!!
咱们先说说里面的术语,"事件捕获"、"事件冒泡"、"事件传播"、"事件注册"、"W3C事件模型"
"事件注册":事件注册有好多方式,大概有下面这些
1、直接在dom元素上加,这其实是很挫的方式,然并卵,现在仍然有好多淫在用
<input type="button" onclick="alert('打的好')" name="button" value="痛击我啊">
2、使用js程序在dom元素对象上加"onxxx"的形式
<input type="button" id="btn" name="button" value="痛击我啊">
document.getElementById('btn').onclick = function(){alert('打的好');};
3、使用诸如'addEventListener'、'attachEvent'函数
var dom = document.getElementById('btn');
var hander = function(){alert('打的好');};
if(dom.addEventListener){
dom.addEventListener('click', hander, false);//支持标准w3c浏览器专用
}else{
dom.attachEvent('onclick', hander);//非标准w3c浏览器专用
}
4、逼格更加高点的"事件委托",意思就是委托别人帮助自己响应事件,如下
<div id="father" style="background: green;">
我是父亲啊</br>
呵呵啊</br>
<div id="son" style="background: blue;">
我是儿子啊
</div>
</div>
document.getElementById('father').onclick = function(event){
event = event || window.event;
var target = event.srcElement || event.target;
if(target.getAttribute('id') === 'son'){ alert('你点击了儿子!');}
}

点击"我是儿子啊"弹出框框,点击"我是父亲啊" 什么都没有弹,当然了,你不仅可以委托父级元素,也可以委托和你无关的元素
"事件冒泡" 和 "事件传播":
两个一起说了,是有历史原因的,早期有两冤家,网景和微软,它俩啥都对着干,网景搞"事件传播",微软对着干搞"事件冒泡",这俩货有啥区别了,网上有人专门画了一张图

"事件冒泡"就是那个绿色的箭头,"事件传播"就是那个红色的箭头
"事件冒泡"就从目标元素"td"一直冒到根"window", "事件传播"就从根"window"一直传到"td"元素, 是不是编程都反着干,真是冤家
这时候联合国"w3c"来了, 这不行啊,不能由着他们乱搞啊,不然这天下不就乱了,但是这两家伙实力比较强,又不能不考虑他们啊,于是W3C采用中和方案制定标准,规定"任何事件首先向下传播直到遇到目标元素,然后再向上冒泡返回" ,这注意好这问题统一了,并且都照顾了大家,我这秘书长位置稳保!!!
所以,你上面看到了两个函数"attachEvent" 和 "addEventListener", 其中"attachEvent"是IE8及其之前的IE浏览器专用,只支持"事件冒泡","addEventListener" 是所有支持
W3C标准事件模型的浏览器专用,即支持"事件冒泡" 又支持 "事件传播"。那对应的取消事件绑定就是 "detachEvent"和"removeEventListener" 两个函数了。那上面那个"event = event || window.event" 也是兼容浏览器用的了,因为IE8及其之前的IE浏览器不能直接获取event对象,需要从window对象获取。
那这个"事件传播"与"事件冒泡" 有啥实际上的区别了,我们还是以一段代码来证明(由于IE8及之前的浏览器只支持"事件冒泡",因此我们这里用chrome浏览器测试)
先HTML代码
<div id="father" style="background: green;">
我是父亲啊</br>
呵呵啊</br>
<div id="son" style="background: blue;">
我是儿子啊
</div>
</div>
界面是

document.getElementById('father').addEventListener('click', function(){
alert('我是父亲!');
}, true);//在事件传播阶段捕获
document.getElementById('son').addEventListener('click', function(event){
alert('我是儿子!');
}, true);//在事件传播阶段捕获
点击"我是儿子啊" 是不是会弹出两次,然后我们换成下面这段再看会弹出几次
document.getElementById('father').addEventListener('click', function(){
alert('我是父亲!');
event.stopPropagation();
}, true);
document.getElementById('son').addEventListener('click', function(event){
alert('我是儿子!');
}, true);
这次只弹出了一次"我是父亲" , "我是儿子" 那句没有执行,这是啥原因了?
因为这里设定在事件传播阶段捕获事件,事件是先传播到'father'元素中的,在'father'元素中调用了'event.stopPropagation()'阻止事件进一步捕获,因此事件将不再传播到'son'元素中 (注意,好多淫把阻止事件传播或者冒泡 与 阻止默认事件 弄混淆了, 阻止默认事件的函数为 'preventDefault' 和 'returnValue = false;', 一个W3C标准浏览器专用,一个IE8及之前版本的IE专用)
再来看在事件冒泡阶段进行捕获,会是怎样的结果,代码如下
document.getElementById('father').addEventListener('click', function(){
alert('我是父亲!');
}, false);
document.getElementById('son').addEventListener('click', function(event){
alert('我是儿子!');
event.stopPropagation();
}, false);
这次再点击"我是儿子啊" 只弹出了"我是儿子","我是父亲" 没有弹出,这是啥原因了?
因为上面代码设定了在事件冒泡阶段捕获,事件先进入传播阶段 传播到'fanther', 'son' 然后到达目标元素 'son', 然后按照W3C的规定 以 事件冒泡 方式返回,先是到达'son', 但是在'son'这里被阻止了,因此不再往上冒泡,只能捕获'son'中的事件了
"事件捕获":看了上面那么多,鄙人觉得这个就不用解释了吧
"W3C事件模型":这个,笔者貌似在上面也解释了,不用说了吧
鄙人才疏学浅,有不足之处,欢迎补足!!!
javascript 事件传播与事件冒泡,W3C事件模型的更多相关文章
- AngularJs 阻止事件运行,防止冒泡穿透事件
ng-click 低啊用方法后 添加语句$event.stopPropagation(); <button type="button" ng-click="doSo ...
- Javascript事件传播
MicroSoft的设计是当事件在元素上触发时,该事件将接着在该节点的父节点触发,以此类推,事件一直沿着DOM树向上传播,直到到达顶层对象document元素.这种自底向上的事件传播方式称为" ...
- JavaScript:事件对象Event和冒泡
本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 绑定事件的两种方式 我们在上一篇文章中已经讲过事件的概念.这里讲一下注册 ...
- js之事件冒泡和事件捕获及其阻止详细介绍
虽然精通jquery,但对它的原型javascript却不是很了解,最近在学习javascript中遇到了一些困难,比如冒泡和捕获,很多次被提到,但又不知究竟应用在何处.找到了一些好文章解惑,在这里分 ...
- js事件(事件冒泡与事件捕获)
事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题. <div id='aa' click='po'> <p id='bb' cli ...
- JS中的事件传播流程
JS中的事件传播流程 1,Javascript与HTML之间的交互是通过事件实现的. 事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间. 可以使用侦听器来预定事件,以便事件发生时执行相应代码. 2 ...
- JavaScript中的事件冒泡?事件传播的解释
注:本文来源 可译网 事件冒泡是你在学习javaScript旅途中遇到的一个术语,它涉及到当一个元素被另一个元素嵌套时调用事件处理的顺序,并且两个元素注册了同一个事件(例如,点击事件). 但是事件冒 ...
- javascript中的事件冒泡、事件捕获和事件执行顺序
谈起JavaScript的 事件,事件冒泡.事件捕获.阻止默认事件这三个话题,无论是面试还是在平时的工作中,都很难避免. DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有 ...
- JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获
先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...
随机推荐
- 关于php中的spl_autoload_register
一.自动加载定义 很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件.一个很大的烦恼是不得不在每个脚本开头写一个长长的包含文件列表(每个类一个文件). 在 PHP 5 中,不再需要 ...
- 存储过程之七—java代码调用
一.简介 jdbc调用存储过程与调用一般的sql语句有些差别.jdbc调用一般的sql语句的时候,返回的是结果集,或是sql语句后是否执行成功的标记量.而存储过程返回的可以是结果集,输出参数.返回状态 ...
- Eclipse,myeclipse开发中常用技巧总结
一.myeclipse自带包和自己部署的包冲突解决问题方案 原来的依赖设置: 修改后的配置: 二.取消Myeclipse的自动文件验证来增加myeclipse速度 1.Windows –> Pe ...
- diff, cmp, patch
diff 以行为单位比较两个文件之间的差异,经常用来查看同一个文件的新旧版本的差异,通常用在文本文件的比较,可以使用重定向'>'制作补丁文档,通常以.patch结尾 \(diff [-bBi] ...
- 制作nginx和php的rpm包
rpm包的制作真几把烦,制作php的rpm花了我3天时间,因为是根据线上环境来做的,依赖的第三方库太多,本来想把所有的第三方库做进php包,后来发现在rpmbuild -bb的时候非常耗时,而且乱七八 ...
- shell exit 0 exit 1
其实都一样,都是退出,只不过返回这个0和1是返回给操作系统的错误或者正确代码. exit 1 指的是脚本运行的返回值,用来指示成功或失败,以及失败的原因. exit 0 表示成功,exit 1表示失败 ...
- quick sort java version
import java.util.Random; public class test { public static void main(String[] args) { int[] arr= gen ...
- NOIP2008 普及组T2 排座椅 解题报告-S.B.S
题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳.同学 ...
- 1.素数判定(如何输出\n,\t,不用关键字冲突)
题目描述 Description 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数. 素数在数论中有着很重要的地位.比1大但不是素数的数称为合数.1和0既非素数也 ...
- AC日记——过河卒 洛谷 1002
题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. ...