DOM事件对象(addEventListener())

转载 2017年01月03日 14:45:46

DOM2事件模型

 

     DOM2事件模型相对于DOM0,小菜仅仅了解如下两点:

          ·  DOM2支持同一dom元素注册多个同种事件。

          ·  DOM2新增了捕获和冒泡的概念。


     DOM2事件通过addEventListener和removeEventListener管理,当然,这是标准。

     但IE8及其以下版本浏览器,自娱自乐,搞出了对应的attachEvent和detachEvent,由于小菜才疏学浅,本文不做讨论。

     addEventListener当然就是注册事件,她有三个参数,分别为:"事件名称", "事件回调", "捕获/冒泡"。举个例子:

复制代码
1 var btn = document.getElementById("test");
2 
3 btn.addEventListener("click", function(e){
4   alert("ok");
5 }, false);

     事件名称就不用多说了,相比DOM0,去掉了前边的on而已。

     事件回调也很好理解,事件触发了总得通知你吧!回调时和DOM0一样,也会默认传入一个event参数,同时this是指触发该事件的dom节点。

     最后一个参数是布尔型,true代表捕获事件,false代表冒泡事件。其实很好理解,先来个示意图:


意思就是说,某个元素触发了某个事件,最先得到通知的是window,然后是document,依次而入,直到真正触发事件的那个元素(目标元素)为止,这个过程就是捕获。接下来,事件会从目标元素开始起泡,再依次而出,直到window对象为止,这个过程就是冒泡。

     为什么要这样设计呢?这貌似是由于深厚的历史渊源,小菜也不怎么了解,就不乱说了。

     由此可以看出,捕获事件要比冒泡事件先触发。

     假设有这样的html结构:

1 <div id="test" class="test">2   <div id="testInner" class="test-inner"></div>3 </div>

     然后我们在外层div上注册两个click事件,分别是捕获事件和冒泡事件,代码如下:

复制代码
 1 var btn = document.getElementById("test");
 2 
 3 //捕获事件 4 btn.addEventListener("click", function(e){
 5   alert("ok1");
 6 }, true);
 7 
 8 //冒泡事件 9 btn.addEventListener("click", function(e){
10   alert("ok");
11 }, false);

     最后,点击内层的div,先弹出ok1,后弹出ok。结合上边的原理图,外层div相当于图中的body,内层div相当于图中最下边的div,证明了捕获事件先执行,然后执行冒泡事件。

     为什么要强调点击内层的div呢?因为真正触发事件的dom元素,必须是内层的,外层dom元素才有机会模拟捕获事件和冒泡事件,从原理图上就看出了。

     如果在真正触发事件的dom元素上注册捕获事件和冒泡事件呢?

     html结构同上,js代码如下:

 1 var btnInner = document.getElementById("testInner");
 2 
 3 //冒泡事件 4 btnInner.addEventListener("click", function(e){
 5   alert("ok");
 6 }, false);
 7 
 8 //捕获事件 9 btnInner.addEventListener("click", function(e){
10   alert("ok1");
11 }, true);

     当然还是点击内层div,结果是先弹出ok,再弹出ok1。理论上应该先触发捕获事件,也就是先弹出ok1,但是这里比较特殊,因为我们是在真正触发事件的dom元素上注册的事件,相当于在图中的div上注册,由图可以看出真正触发事件的dom元素,是捕获事件的终点,是冒泡事件的起点,所以这里就不区分事件了,哪个先注册,就先执行哪个。本例中,冒泡事件先注册,所以先执行。

     这个道理适用于多个同种事件,比如说一下子注册了3个冒泡事件,那么执行顺序就按照注册的顺序来,先注册先执行。例如:

 1 var btnInner = document.getElementById("testInner");
 2 
 3 btnInner.addEventListener("click", function(e){
 4   alert("ok");
 5 }, false);
 6 
 7 btnInner.addEventListener("click", function(e){
 8   alert("ok1");
 9 }, false);
10 
11 btnInner.addEventListener("click", function(e){
12   alert("ok2");
13 }, false);

     结果当然是依次弹出ok、ok1、ok2。

     为了进一步理解事件模型,还有一种场景,假如说外层div和内层div同时注册了捕获事件,那么点击内层div时,外层div的事件一定是先触发的,代码如下:

 1 var btn = document.getElementById("test");
 2 var btnInner = document.getElementById("testInner");
 3 
 4 btnInner.addEventListener("click", function(e){
 5   alert("ok");
 6 }, true);
 7 
 8 btn.addEventListener("click", function(e){
 9   alert("ok1");
10 }, true);

     结果是先弹出ok1。

     假如外层div和内层div都是注册的冒泡事件,点击内层div时,一定是内层div事件先执行,原理相同。

     细心的读者会发现,对于div嵌套的情况,如果点击内层的div,外层的div也会触发事件,这貌似会有问题!

     点击的明明是内层div,但是外层div的事件也触发了,这的确是个问题。

     其实,事件触发时,会默认传入一个event对象,前边提过了,这个event对象上有一个方法:stopPropagation,通过此方法,可以阻止冒泡,这样外层div就接收不到事件了。代码如下:

 1 var btn = document.getElementById("test");
 2 var btnInner = document.getElementById("testInner");
 3 
 4 btn.addEventListener("click", function(e){
 5   alert("ok1");
 6 }, false);
 7 
 8 btnInner.addEventListener("click", function(e){
 9   //阻止冒泡10 e.stopPropagation();
11   alert("ok");
12 }, false);

     终于要说说怎么解除事件了。解除事件语法:btn.removeEventListener("事件名称", "事件回调", "捕获/冒泡");

     这和绑定事件的参数一样,详细说明下:

 

          ·  事件名称,就是说解除哪个事件呗。

          ·  事件回调,是一个函数,这个函数必须和注册事件的函数是同一个。

          ·  事件类型,布尔值,这个必须和注册事件时的类型一致。

 

     也就是说,名称、回调、类型,三者共同决定解除哪个事件,缺一不可。举个例子:

 1 var btn = document.getElementById("test");
 2 //将回调存储在变量中 3 var fn = function(e){
 4   alert("ok");
 5 };
 6 //绑定 7 btn.addEventListener("click", fn, false);
 8 
 9 //解除10 btn.removeEventListener("click", fn, false);
     要想注册过的事件能够被解除,必须将回调函数保存起来,否则无法解除。

深入理解DOM中的事件对象

在触发DOM上的某个事件时,会在事件处理程序函数中会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。先看个例子:var b...
  • code_ja
  • code_ja
  • 2016年07月15日 21:23
  • 964

[JavaScript]onclick、addEventListener、attachEvent详解

onclick addEventListener attachEvent onclickonclick 最初的样子: window.addEventListener("click", functio...
  • csdn_yudong
  • csdn_yudong
  • 2017年04月13日 11:18
  • 667

addEventListener-event 对象的属性和方法(firefox)

事件触发时,会将一个 Event 对象传递给事件处理程序,比如: document.getElementById("testText").addEventListener("keydown", fu...
  • zhaokuner
  • zhaokuner
  • 2012年05月08日 16:06
  • 3854

事件处理---addEventListener

addEventListener 用于注册事件处理程序,IE 中为 attachEvent,我们为什么讲 addEventListener 而不讲 attachEvent 呢?一来 attachE...
  • ios0213
  • ios0213
  • 2016年06月16日 14:36
  • 642

DOM Event (javascript 各种事件整理汇总)

DOM 事件: 鼠标事件 点击事件: down>up>click 冒泡 移动 overover>enter,out>leave over和out冒泡,enter和leave步冒泡; move 冒泡 ...
  • lisulong1
  • lisulong1
  • 2016年01月17日 14:54
  • 532

DOM事件 中的 focus 和blur

今天做一个表单验证时 ,遇到一个问题,利用form.addEventListener 绑定事件时,发现focus 不起作用 通过查阅资料 终于知道了问题出在哪里? (资料出处https://devel...
  • alonia
  • alonia
  • 2016年05月10日 16:46
  • 278

DOM事件大全

1.事件:js与html的交互就是通过事件 的,观察者模式 2.事件流:从页面中接收事件的顺序 IE::事件冒泡流,事件冒泡,事件从最具体的元素接收,然后逐级向上传播,主流浏览器都支持 Netsc...
  • jianruoche
  • jianruoche
  • 2017年08月21日 15:27
  • 97

HTML addEventListener() 方法和attachEvent()区别分析

本文转自:http://www.runoob.com/jsref/met-element-addeventlistener.html 语法 element.addEventListener(ev...
  • ssisse
  • ssisse
  • 2016年05月06日 20:52
  • 965

细说addEventListener与事件捕获、事件冒泡

这篇文章详细介绍了addEventListener绑定事件的细节以及事件冒泡和事件捕获的有关知识。作者以生动形象的例子和简单直白的语言,让读者能够快速了解和掌握JS中事件绑定和事件传播的规则和本质。...
  • Hukaihe
  • Hukaihe
  • 2016年06月28日 23:20
  • 13961

手动触发事件

DoM 2级事件提供了一个创建新event对象的方法:createEvent() createEvent()接收一个参数'eventType' createEvent()返回的对象取决于eventT...
  • acs1899
  • acs1899
  • 2013年08月20日 15:47
  • 758
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DOM事件对象(addEventListener())
举报原因:
原因补充:

(最多只允许输入30个字)