Javascript程序使用的是事件驱动的设计模式,为一个元素添加事件监听函数,当这个元素的相应事件被触发那么其添加的事件监听函数就被调用:

<input type="button" onclick="alert('Button Click')" />

当上面的button被点击后,会弹出一个框显示“Button Click”.



在javascript中添加事件监听函数有多种方法,比如:

在html元素上 

[xhtml] view
plain
copy

  1. <input type="button" id="myButton" onclick="alert('Button Click')" />

用上述元素对应的js属性 

[javascript] view
plain
copy

  1. document.getElementById("myButton").onclick = function () {
  2. alert("Button Click");
  3. }



用统一的添加函数 

[javascript] view plaincopy

  1. document.getElementById("myButton").addEventListener("click",
  2.   function() {
  3.   alert("Button Click");
  4.   },
  5.   true)

这几种方法在作用域,事件传播等方面都有区别,这就是所谓的0级DOM,2级DOM事件模型的区别。让我们来看下何谓0级DOM,2级DOM。





0级DOM: 



一开始浏览器处理事件的时候只有原始事件模型,事件处理程序被设置为js代码串作为html的性质值,例如:

[xhtml] view
plain
copy

  1. <input id="myButton" type="button" value="Press Me" onclick="alert('thanks');" >

在js中html元素都有一个对应的对象,这个对象的属性对应那个html元素的性质,所以可以用js代码添加事件监听函数

[javascript] view
plain
copy

  1. document.getElementById("myButton").onclick = function () {
  2. alert('thanks');
  3. }

通常情况下事件监听函数如果返回一个值并且是false,则会阻止浏览器执行默认的动作。无论用html还是js,都是把一个函数赋值给文档元素,在事件监听函数被调用时候它是作为产生事件的元素的放法调用的,所以this引用的是那个目标元素(例子中的Input对象)。



从技术上来说,W3C的DOM标准并不支持上述最原始的添加事件监听函数的方式,这些都是在DOM标准形成前的事件模型。尽管没有正式的W3C标准,但这种事件模型仍然得到广泛应用,这就是我们通常所说的0级DOM。 



2级DOM: 



DOM级别1于1998年10月1日成为W3C推荐标准。1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。在2级DOM中除了定义了一些DOM相关的操作之外还定义了一个事件模型 ,这个标准下的事件模型就是我们所说的2级DOM事件模型 



2级DOM的事件传播 

 在2级DOM中,当事件发生在节点时,目标元素的事件处理函数就被触发,而且目标的每个祖先节点也有机会处理那个事件。因为2级DOM的事件传播分三个阶段进行。第一,在capturing阶段,事件从Document对象沿着文档树向下传播给节点。如果目标的任何一个祖先专门注册了事件监听函数,那么在事件传播的过程中就会运行这些函数。下一个阶段发生在目标节点自身,直接注册在目标上的适合的事件监听函数将运行。第三阶段是bubbling阶段,这个阶段事件将从目标元素向上传播回Document对象(与capturing相反的阶段)。虽然所有事件都受capturing阶段的支配,但并不是所有类型的事件都bubbling。(0级DOM事件模型处理没有capturing阶段)
如:

[xhtml] view
plain
copy

  1. <span>
  2. <a></a>
  3. </span>

点击a后capturing阶段事件传播会从document-> span->a,然后发生在a,最后bubbling阶段事件传播会从a->span->document 。



2级DOM的事件监听函数注册

2级事件模型中,可以调用对象的addEventListener()方法为元素设置事件监听函数,也就是说通过2级DOM的这个API注册的函数才有可能在上述事件传播三个阶段中任意一个阶段捕捉到事件的发生(如果用0级DOM的2个方法赋值的事件监听函数不能在capturing阶段捕捉到事件)。

1 .addEventListener第一个参数是String,事件类型名,没有前缀on,比如要注册click事件就传入“click”

,不是“onclick”

2 .第二个参数是监听函数,在调用的时候js会传给他一个Event对象,这个对象放了有关事件的细节,如果调用的这个对象的stopPropagation()方法,则会阻止事件传播进一步传播(比如在第一个阶段捕捉到事件并运行事件监听函数,其中调用了event。stopPropagation则事件就不会再被传播经历第二第三阶段了) 

3 .第三个参数是boolean,true表示事件监听函数能够在三个阶段中的任意一个阶段捕捉到事件(符合2级DOM标准),如果是false就表示事件监听函数不能在capturing阶段捕捉到事件(表现同0级DOM)。



2级DOM中监听函数中的this

通过addEventListener添加的函数中的this,标准中并没有规定this必须指向目标元素, 尽管大多数浏览器都是这么实现的,但最终还是取决于浏览器的实现,我们需要用到目标元素的时候请调用event.currentTarget. 



2级DOM的Event对象 

 用addEventListener添加的事件监听函数,在被调用的时候js会传给他一个Event对象,下面就是这个Event对象的常用属性

type: 

       发生的事件的类型,例如"click", "mouseover"

target: 

       发生事件的节点,可能与currentTarget不同

currentTarget: 

    正在处理事件的节点,如果在capturing阶段和冒泡阶段处理事件,这个属性就与target属性不同。在事件监听函数中应该用这个属性而不是this

stopPropagation(): 

    可以阻止事件从当前正在处理他的节点传播

preventDefault(): 

    阻止浏览器执行与事件相关的默认动作,与0级DOM中返回false一样

clientX, clientY: 

    鼠标相对于浏览器的x坐标y坐标

screenX, screenY: 

    鼠标相对于显示器左上角的x坐标y坐标





IE事件模型

1.Event对象不是传递给事件监听函数,而是通过Window对象的event属性访问Event对象.

2.IE Event对象常用属性

type:

兼容DOM的type属性

srcElement:       

兼容DOM的target属性

clientX, clientY:

兼容DOM的clientX, clientY属性

cancelBubble: 

       布尔值,设为true同调用stopPropagation()

returnValue: 

       布尔值,设为false同调用preventDefault()

             

3.事件监听函数注册

没有addEventListener,只有attachEvent。2个参数,同addEventListener前两个,只是事件名带前缀on。 IE事件模型没有capturing阶段所以调用attachEvent相当于调用addEvetnListener且第三个参数为false:

[javascript] view
plain
copy

  1. document.getElementById("myTest").attachEvent("onclick", function(){alert(1)});

相当于

[javascript] view
plain
copy

  1. document.getElementById("myTest").addEventListener("click", function(){alert(1)}, false);

4.用attachEvent注册的函数将被作为全局函数调用,而不是作为发生事件的文档元素的方法,也就是说this引用的是Window对象,而不是事件的目标元素。

javascript中0级DOM和2级DOM事件模型浅析 分类: C1_HTML/JS/JQUERY 2014-08-06 15:22 253人阅读 评论(0) 收藏的更多相关文章

  1. 苹果应用商店AppStore审核中文指南 分类: ios相关 app相关 2015-07-27 15:33 84人阅读 评论(0) 收藏

    目录 1. 条款与条件 2. 功能 3. 元数据.评级与排名 4. 位置 5. 推送通知 6. 游戏中心 7. 广告 8. 商标与商业外观 9. 媒体内容 10. 用户界面 11. 购买与货币 12. ...

  2. 详解Objective-C的meta-class 分类: ios相关 ios技术 2015-03-07 15:41 51人阅读 评论(0) 收藏

    比较简单的一篇英文,重点是讲解meta-class.翻译下,加深理解. 原文标题:What is a meta-class in Objective-C? 原文地址:http://www.cocoaw ...

  3. ubuntu常用文件搜索命令 分类: linux 学习笔记 ubuntu 2015-07-05 15:40 84人阅读 评论(0) 收藏

    1.find find [搜索路径] [搜索关键字] 比如查找/test中文件名为t5.tmp的文件: 查找根目录下大于100M的文件 注意,这里的204800单位是块,1块=512字节 在根目录下查 ...

  4. 搜狗输入法皮肤安装 分类: windows常用小技巧 2014-05-04 15:10 172人阅读 评论(0) 收藏

    第一步: 下载皮肤,皮肤是.ssf格式的. 第二步: 找到安装目录:(以我的为例) D:\软件\搜狗输入法\SogouInput\7.1.0.1652\AllSkin: 把下载的皮肤剪切(或复制)到此 ...

  5. shell入门之变量测试 分类: 学习笔记 linux ubuntu 2015-07-10 15:49 31人阅读 评论(0) 收藏

    格式:test 测试条件 字符串测试: 注意空格: test str1 == str2 测试字符串是否相等 test str1 != str2 测试字符串是否不相等 test str1 测试字符串是否 ...

  6. codeforces815A Karen and Game 2017-06-27 15:22 31人阅读 评论(0) 收藏

    C. Karen and Game time limit per test 2 seconds memory limit per test 512 megabytes input standard i ...

  7. adb常用命令 分类: H1_ANDROID 2013-09-08 15:22 510人阅读 评论(0) 收藏

    安装软件  adb install apk文件名称.apk  重新安装该软件  adb install -r apk文件名称.apk  卸载apk软件  adb uninstall apk包名.apk ...

  8. C语言中返回字符串函数的四种实现方法 2015-05-17 15:00 23人阅读 评论(0) 收藏

    C语言中返回字符串函数的四种实现方法 分类: UNIX/LINUX C/C++ 2010-12-29 02:54 11954人阅读 评论(1) 收藏 举报 语言func存储 有四种方式: 1.使用堆空 ...

  9. C# 字符串常用操作 分类: C# 2014-08-22 15:07 238人阅读 评论(0) 收藏

    string str1 = "C#操作字符串<几种常见方式>如下"; string str2 = "C#操作字符串";     //比较字符串 Co ...

随机推荐

  1. ubuntu-12.04工作区内容变换所属工作区

    最近一直纠结于ubuntu12.04窗口更改所属工作区问题,今天在网上看到了方法.记录下来 主要就是利用快捷键. 1.打开你想移动的窗口 2.使用快捷键Shift + Ctrl + Alt + Dow ...

  2. php课程 12-40 抽象类的作用是什么

    php课程 12-40 抽象类的作用是什么 一.总结 一句话总结:定标准的 1.继承的关键词有哪两个? extendsparent 2.抽象类的实际意义是什么? 制造符合规范的产品你必须实现了抽象类里 ...

  3. php资源类型变量

    php资源类型变量 一.总结 1. php资源类型变量:用来打开文件.数据库连接.图形画布区域等的一种特殊变量,比如FILE *fp;  二.PHP: Resource 资源类型 Resource 资 ...

  4. Day3上午解题报告

    预计分数:100+40+50=190 实际分数:100+40+50=190 T1 https://www.luogu.org/problem/show?pid=T15365 表示从来没做过博弈论的题, ...

  5. Codefroces 812 B. Sagheer, the Hausmeister

    http://codeforces.com/problemset/problem/812/B B. Sagheer, the Hausmeister time limit per test 1 sec ...

  6. 关于Webpack详述系列文章 (第三篇)

    1. 类图 1. 模块 Module是webpack中最核心的类,要加载定的一切和依赖都是Module. 它有很多子类 RawModule NormalModule MultiModule Conte ...

  7. SpringBoot+springmvc异步处理请求

    有两种情况,第一种是业务逻辑复杂,但不需要业务逻辑的结果,第二种是需要返回业务逻辑的处理结果 第一种比较简单,利用多线程处理业务逻辑,或者利用spring中@Asyn注解更简单, 使用@Asyn注解, ...

  8. 洛谷——P1316 丢瓶盖

    https://www.luogu.org/problem/show?pid=1316 题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想 ...

  9. 15.lambda表达式

    #include <iostream> #include <array> using namespace std; //解决函数怀孕现象 //[](){} //[] =引用,只 ...

  10. C语言深度解剖读书笔记

    开始本节学习笔记之前,先说几句题外话.其实对于C语言深度解剖这本书来说,看完了有一段时间了,一直没有时间来写这篇博客.正巧还刚刚看完了国嵌唐老师的C语言视频,觉得两者是异曲同工,所以就把两者一起记录下 ...