DOM2事件传播机制

事件

JavaScriptHTML的交互是通过事件实现的。JavaScript采用异步事件驱动编程模型,当文档、浏览器、元素或与之相关对象发生特定事情时,浏览器会产生事件。如果JavaScript关注特定类型事件,那么它可以注册当这类事件发生时要调用的句柄

事件是某个行为或者触发,比如点击、鼠标移动

  • 当用户点击鼠标时
  • 当网页已加载时
  • 当图像已加载时
  • 当鼠标移动到元素上时
  • 当用户触发按键时...

事件流

事件流描述的是从页面中接收事件的顺序,比如有两个嵌套的div,点击了内层的div,这时候是内层的div先触发click事件还是外层先触发?目前主要有三种模型

  • 事件冒泡模型


    事件冒泡模型
  • 事件捕获模型


    事件捕获模型
  • DOM事件流


    DOM事件流
  • 事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的元素
  • 事件捕获:不太具体的节点更早接收事件,而最具体的元素最后接收事件,和事件冒泡相反
  • DOM事件流:DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段

这种分歧在日常生活中也很常见,举个例子,某个地方出了抢劫事件,我们有多种处理方式
村里先发现,报告给乡里,乡里报告到县城,县城报告给市里。。。。
市里先知道这事儿,然后交代给县城怎么处理,县城交给到乡里处理,乡里交给村里处理

Opera、Firefox、Chrome、Safari都支持DOM事件流,IE不支持事件流,只支持事件冒泡

二、事件处理程序

DOM0级事件处理程序

例子:

1 var btn5 = document.getElementById('btn5');
2 btn5.onclick=function(){
3    console.log(this.id);//btn5   
4 };

注意:基于DOM0的事件,对于同一个dom节点而言,只能注册一个,后边注册的 同种事件 会覆盖之前注册的。利用这个原理我们可以解除事件,btn5.onclick=null;其中this就是绑定事件的那个元素;

以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理

DOM2级事件处理程序

DOM2支持同一dom元素注册多个同种事件,事件发生的顺序按照添加的顺序依次触发(IE是相反的)。
DOM2事件通过addEventListenerremoveEventListener管理

addEventListener(eventName,handlers,boolean); removeEventListener(),两个方法都一样接收三个参数,第一个是要处理的事件名,第二个是事件处理程序,第三个值为false时表示在事件冒泡阶段调用事件处理程序,一般建议在冒泡阶段使用,特殊情况才在捕获阶段;
注意:通过addEventListener()添加的事件处理程序只能用removeEventListener()来移除,并且移除时传入的参数必须与添加时传入的参数一样;比如

示例

var btn2 = document.getElementById('btn2');
var handlers = function () {
   console.log(this.id);
};

btn2.addEventListener('click',handlers,false);

btn2.removeEventListener('click',handlers.false);

三、事件传播机制

当一个事件发生以后,它会在不同的DOM节点之间传播(propagation)。这种传播分为三个阶段:


第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。
这种三阶段的传播模型,会使得一个事件在多个节点上触发。

比如:

<div>
    <p>Click Me</p>
</div>

如果对这两个节点的click事件都设定监听函数,则click事件会被触发四次。<div><p>节点的捕获阶段和冒泡阶段各一次:

  1. 捕获阶段:事件从<div><p>传播时,触发<div>click事件;
  2. 目标阶段:事件从<div>到达<p>时,触发<p>click事件;
  3. 目标阶段:事件离开<p>时,触发<p>click事件;
  4. 冒泡阶段:事件从<p>传回<div>时,再次触发<div>click事件。
    用户点击网页的时候,浏览器总是假定click事件的目标节点,就是点击位置的嵌套最深的那个节点。所以<p>节点的捕获和冒泡阶段都会显示为target阶段。

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方法有等同效果。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 3,480评论 1 11
  • js之事件机制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驱动...
    道无虚阅读 2,347评论 1 3
  • JavaScript 程序采用了异步事件驱动编程模型。在这种程序设计风格下,当文档、浏览器、元素或与之相关的对象发...
    劼哥stone阅读 1,253评论 3 11
  • 事件流 JavaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互...
    DHFE阅读 826评论 0 3
  • JavaScript 与 HTML 之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬...
    threetowns阅读 340评论 0 0