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事件模型":这个,笔者貌似在上面也解释了,不用说了吧

鄙人才疏学浅,有不足之处,欢迎补足!!!

时间: 2024-12-06 03:10:42

javascript 事件传播与事件冒泡,W3C事件模型的相关文章

AngularJs 阻止事件运行,防止冒泡穿透事件

ng-click 低啊用方法后 添加语句$event.stopPropagation(); <button type="button" ng-click="doSomeSth();$event.stopPropagation();">button</button>

JavaScript:事件对象Event和冒泡

本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 绑定事件的两种方式 我们在上一篇文章 DOM操作详解 中已经讲过事件的概念.这里讲一下注册事件的两种方式,我们以onclick事件为例. 方式一:onclick 举例: <body> <button>点我</button> <script> var btn = document.getElementsByTagName("

js之事件冒泡和事件捕获及其阻止详细介绍

虽然精通jquery,但对它的原型javascript却不是很了解,最近在学习javascript中遇到了一些困难,比如冒泡和捕获,很多次被提到,但又不知究竟应用在何处.找到了一些好文章解惑,在这里分享给大家 一.事件的发生顺序 这个问题的起源非常简单,假设你在一个元素中又嵌套了另一个元素 复制代码代码如下: -----------------------------------| element1                        ||   --------------------

冒泡型事件、捕获型事件

冒泡型事件的基本思想是.事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发. <html>        <head>            <title></title>     </head>         <body onclick="theClick()">         <div onclick="theClick()">点击</di

JS中的事件传播流程

JS中的事件传播流程 1,Javascript与HTML之间的交互是通过事件实现的. 事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间. 可以使用侦听器来预定事件,以便事件发生时执行相应代码. 2,DOM事件流存在三个阶段:事件捕获阶段,处于目标阶段,事件冒泡阶段. 事件流:事件发生时,事件在元素节点与根节点之间的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即DOM事件流.事件传播顺序的两种事件流模型:事件冒泡,事件捕获. 事件捕获(event capturing):事件从最不

Js事件传播流程

Js事件传播流程 js事件传播流程主要分三个阶段:事件捕获阶段.处于目标阶段.事件冒泡阶段. 在我们平常用的addEventListener方法中,一般只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数,然而,addEventListener还可以传入第三个参数,第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数.   (1). 捕获阶段:事件从根节点流向目标节点,途中流经各个DOM节点,在各个节点上触发捕获

JavaScript中的事件冒泡?事件传播的解释

注:本文来源  可译网 事件冒泡是你在学习javaScript旅途中遇到的一个术语,它涉及到当一个元素被另一个元素嵌套时调用事件处理的顺序,并且两个元素注册了同一个事件(例如,点击事件). 但是事件冒泡仅仅是难题的一部分.它经常和事件捕获和事件传播一起被提及,并且对这三个概念有着很深的了解是学习javaScript事件必不可少的,例如,假如你想实现事件委托. 在这篇文章中,我会解释这些术语,并展示它们如何组合在一起.我还将向您展示如何对JavaScript事件流的基本了解可以让您对应用程序进行细

Javascript事件传播(冒泡机制) (摘自 博客园 萍水相逢)

今天在使用javascript弹出菜单时遇到了问题,搞了一晌终于算有点眉目了.和大家一起分享下.有什么不对的地方希望大家多多留言评论. 定义:JavaSciprt事件中有两个很重要的特性:事件冒泡 以及目标元素 . 事件冒泡: 当一个元素上的事件被触发的时候,比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发.这一过程被称为事件冒泡:这个事件从原始元素开始一直冒泡到DOM树的最上层. 目标元素: 任何一个事件的目标元素都是最开始的那个元素,并且它在我们的元素对象中以属性的形

看懂此文,不再困惑于javascript中的事件绑定、事件冒泡、事件捕获和事件执行顺序

最近一个项目基于3维skyline平台,进行javascript二次开发.对skyline事件的设计真是无语至极,不堪折磨啊!抽空学习了下javascript和jquery的事件设计,收获颇大,总结此贴,和大家分享. (一)事件绑定的几种方式 javascript给DOM绑定事件处理函数总的来说有2种方式:在html文档中绑定.在js代码中绑定.下面的方式1.方式2属于在html中绑定事件,方式3.方式4和方式5属于在js代码中绑定事件,其中方法5是最推荐的做法. 方式1: HTML的DOM元素