1.javascript中为元素添加事件处理程序的方法
有以下几种方式,可以为javascript元素添加事件处理程序

(1) 直接将事件处理代码写在html中
(2) 定义一个函数,赋值给html元素的onXXX属性
(3) 使用element.onXXX方式
以上三种方式,请看下面代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>添加事件的方法</title>
<style>
div {border:1px solid blue;margin:10px;}
div#divGrandpa {padding:10px;background-color:#aaaaaa;}
div#divFather {padding:10px;background-color:#bbbbbb;}
div#divSon {padding:10px;background-color:#cccccc;}
</style> </head>
<body>
<div id="divGrandpa" style="width:500px;height:20px;" onclick="alert('直接将事件处理代码写在html中');">(1) 直接将事件处理代码写在html中 </div> <div id="divFather" style="width:500px;height:20px;" onclick="clk()" >(2) 定义一个函数,赋值给html元素的onXXX属性 </div> <div id="divSon" style="width:500px;height:20px;" >(3) 使用element.onXXX方式 </div> </div> </body>
<script>
function clk()
{
alert('定义一个函数,赋值给html元素的onXXX属性');
} function clk1()
{
alert('使用element.onXXX方式');
} var clkEle = document.getElementById('divSon');
//这种方式,必须将本行代码放到上面的html代码<div id="divSon" ...>后面,
//否则导致找不到divSon,返回null
clkEle.onclick = clk1;
</script>
</html>

(4) 使用addEventListener或attachEvent

这是目前推荐的方式,较前两种方式功能更为强大,可以为元素添加多个事件handler,
支持事件冒泡或捕获,前三种方式默认都是冒泡。
IE6/7/8仍然没有遵循标准而使用了自己专有的attachEvent,且不支持事件捕获。
注意attachEvent的第一个参数需要加上个"on",比如click事件时,传递参数需要是on+click=onclick
addEventListener第三个参数为false表示事件冒泡,true
attachEvent没有第三个参数,默认就是冒泡,没有捕获。
这种方式代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>浏览器事件机制——冒泡处理</title>
<style>
div {border:1px solid blue;}
div#divGrandpa {padding:40px;background-color:#f00;}
div#divFather {padding:40px;background-color:#0f0;}
div#divSon {padding:40px;background-color:#00f;}
</style>
</head>
<body>
<div id="divGrandpa" style="width:300px;height:200px;" > I am Grandpa
<div id="divFather" style="width:200px;height:120px;" > I am father
<div id="divSon" style="width:100px;height:40px;" >
点击我 I am son
</div>
</div>
</div>
<script>
function showSon()
{
alert("I am son");
} function showFather()
{
alert("I am father");
} function showGrandpa()
{
alert("I am Grandpa");
} var grandpa = document.getElementById("divGrandpa");
var father = document.getElementById("divFather");
var son = document.getElementById("divSon"); if(window.addEventListener)
{
grandpa.addEventListener("click", showGrandpa, true);
father.addEventListener("click", showFather, true);
son.addEventListener("click", showSon, true);
}
else if (window.attachEvent)
{
grandpa.attachEvent("onclick", showGrandpa);
father.attachEvent("onclick", showFather);
son.attachEvent("onclick", showSon);
}
</script>
</body>
</html>

2. 事件模型与事件传播

javascript的事件模型可以分为2个级别DOM0,DOM1,DOM2
(参考:http://www.trans4fun.org/2011/12/%E3%80%90javascript%E4%BA%8B%E4%BB%B6%E7%B3%BB%E5%88%97%E3%80%91dom%E4%BA%8B%E4%BB%B6%E6%9C%BA%E5%88%B6%E7%AE%80%E6%98%8E%E6%95%99%E7%A8%8B/)
注:这里DOM1级别的似乎有误,没有DOM1级别事件.
注:似乎有DOM3了,但是貌似跟事件关系不大,可参考http://blog.sina.com.cn/s/blog_825442790101354v.html

前面说的添加时间处理程序方式(1)(2)(3)中处理方式就是DOM0级别的,

方式(3)的好处是将JavaScript和HTML分离开来。
它通过给HTML元素设置一个属性,该属性是一个回调函数来实现事件的注册。
然而,这种方式给一个元素的同一事件只允许一个处理器。

方式(4)是DOM级别2,对于DOM级别2的事件最大的好处就是一个事件可以注册许多处理器。
不仅如此,你还可以指定处理器是在捕获阶段还是冒泡阶段被触发(
通过设置”addEventListener()”函数的第三个参数来指定 – true表示在捕获阶段,false表示在冒泡阶段)

(注:没有DOM1级的事件:DOM级别1于1998年10月1日成为W3C推荐标准。
1级DOM标准中并没有定义事件相关的内容,所以没有所谓的1级DOM事件模型。
参考:http://blog.ueder.info/333.html)

事件传播的过程详解:
(1)DOM0级的事件模型中,浏览器把时间分派给发生事件的文档元素,那个对象具有适合的时间句柄,就运行这个句柄.
除此之外,不用执行其他操作.(摘自JavaScript权威指南,犀牛书第5版400页.)
实际测试发现,DOM0级别的方式定义的事件,默认是冒泡的.
比如下面的代码:
在div标签的onclick的onclick属性中指定事件处理函数.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk" />
<title>浏览器事件机制——冒泡处理</title>
<style>
div {border:1px solid blue;}
div#divGrandpa {padding:40px;background-color:#f00;}
div#divFather {padding:40px;background-color:#0f0;}
div#divSon {padding:40px;background-color:#00f;}
</style>
</head>
<body>
<div id="divGrandpa" style="width:300px;height:200px;" onclick="showGrandpa();" > I am Grandpa
<div id="divFather" style="width:200px;height:120px;" onclick="showFather();"> I am father
<div id="divSon" style="width:100px;height:40px;" onclick="showSon();" >
点击我 I am son
</div>
</div>
</div>
<script>
function showSon()
{
alert("I am son");
} function showFather()
{
alert("I am father");
} function showGrandpa()
{
alert("I am Grandpa");
}
</script>
</body>
</html>

当点击蓝色部分(son)时,依次触发son,father,grandpa的div的onclick事件,
可见这个事件传播过程中,事件对象是向上冒泡的.
这个过程可分解为:
鼠标单击 -> 浏览器生成单击事件 -> 浏览器把单击事件分派给son(div) -> div(son)执行单击处理函数 ->
事件对象往上传播(即往document对象传播,往body标签方向传播) -> 传播到 father,执行father的click事件处理函数 ->
事件对象传播到grandpa,执行grandpa的click事件处理函数.
(2)DOM2级的事件模型中,事件的传播分三个阶段:
a.事件捕捉阶段,事件对象沿着document一直传播到发生事件的那个对象(即文档的目标节点,比如id为son的div),这个过程叫事件捕获.
b.事件到达目标节点,如果目标节点指定了事件处理函数,则执行这个函数
c.事件自目标节点向上,沿着a相反的方向再次传播到document对象,这个过程叫做事件冒泡.
使用addEventListener或attachEvent方式注册的事件处理函数,就是这种DOM2级的事件处理函数.
这里有两个函数是因为addEventListener是标准浏览器中的函数,而attachEvent是IE专用的,不是标准浏览器函数.
使用addEventListener方式注册事件处理函数后,
在事件传播过程中的a,b,c三个阶段中经过的节点都有可能执行该节点注册的事件处理函数,比如在过程a中,对于单击事件来说,
如果目标节点的任何一个祖先节点注册了单击事件处理函数,则在过程a中就有机会执行这个祖先节点的
单击事件处理函数.

addEventListener函数调用方式如下:
grandpa.addEventListener("click", showGrandpa, true);第一个参数是事件名称,第二个参数是事件处理函数名,
第三个参数为true表示在事件捕获阶段可以执行这个事件处理函数,为false表示不在事件捕获阶段执行该事件处理函数,
而是在事件冒泡阶段执行时间处理函数(这也是默认的方式,DOM0级别事件处理方式)
因为第三个参数要么为true要么为false,所以使用addEventListener注册的事件处理函数要么在捕获阶段执行(第三个参数=true),
要么在冒泡阶段执行(第三个参数=false),
addEventListener注册的事件处理函数 不会 同时在 捕获和冒泡阶段执行.
attachEvent方式注册事件处理函数,是IE专用的,非标准.事件传播过程只有b和c,即没有事件捕获过程.
因为attachEvent注册的事件处理函数只在冒泡阶段执行,所以这个函数没有第三个参数.
调用方式为:grandpa.attachEvent("onclick", showGrandpa);
需要注意的是,第一个参数,需要在事件名称前面加上on.
3. 事件对象
在执行监听函数时,会传入一个event对象,其实有一些常用的属性我们会经常用到:
type:
发生事件的类型,如click , mouseover, mouseout等
target:
发生事件的节点可能与currentTarget不同
currentTarget:
正在处理事件的节点,如果在capturing阶段和冒泡阶段处理事件,这个属性就与target属性不同。在事件监听函数中应该用这个属性而不是this
stopPropagation():
可以阻止事件从当前正在处理他的节点传播
preventDefault():
阻止浏览器执行与事件相关的默认动作,与0级DOM中返回false一样
clientX, clientY:
鼠标相对于浏览器的x坐标y坐标
screenX, screenY:
鼠标相对于显示器左上角的x坐标y坐标
IE下的处理方式
IE下没有addEventListener,但是有自己类似的方法:attachEvent,这个方法只有两个参数,第一个参数为事件类型的前面需要加”on”,由于 ie下没有捕获,所以没有类似标准浏览器的第三个参数。
IE上可以对元素进行多次同样的绑定,标准浏览器只会绑定一次。ie下event对象不是事件处理程序传入的参数,而是全局的变量:window.event,例如中断冒泡用window.event.cancelBubble = true.
event常用属性
type:
兼容DOM的type属性
srcElement:
兼容DOM的target属性
clientX, clientY:
兼容DOM的clientX, clientY属性
cancelBubble:
布尔值,设为true同调用stopPropagation()
returnValue:
布尔值,设为false同调用preventDefault()
卸载方法:
Object.removeEventListener(eventType,handler,useCapture);//DOM标准的事件卸载方式
Object.detachEvent(eventType,handler);//IE内核的事件卸载方式
4 事件传播过程的阻止
浏览器在执行事件处理函数都会传递一个event对象,改event对象有个
stopPropagation()方法可以阻止事件对象的传播(阻止捕获和冒泡).

说说JavaScript中的事件模型的更多相关文章

  1. 理解javascript中的事件模型

    javascript中有两种事件模型:DOM0,DOM2.而对于这两种的时间模型,我一直不是非常的清楚,现在通过网上查阅资料终于明白了一些. 一.  DOM0级事件模型 DOM0级事件模型是早期的事件 ...

  2. JavaScript中的事件模型

    JS中的事件 1.鼠标事件 onclick   ondbclick   onmouseover   onmouseout 2.HTML事件 onload   onunload   onsubmit   ...

  3. 深入理解javascript中的事件循环event-loop

    前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...

  4. javascript 中的事件机制

    1.javascript中的事件. 事件流 javascript中的事件是以一种流的形式存在的. 一个事件会也有多个元素同时响应. 有时候这不是我们想要的效果, 我们只是需要某个特定的元素相应我们的绑 ...

  5. JavaScript中的事件对象

    JavaScript中的事件对象 JavaScript中的事件对象是非常重要的,恐怕是我们在项目中使用的最多的了.在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含这所有与事件有 ...

  6. JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获

    先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...

  7. 了解javascript中的事件(二)

    本文目录如下: 零.寒暄 一.事件的分类 二.事件代理 2.1 问题引出 2.2 什么是事件代理 2.3 完整示例 二.事件代理 三.事件代理思想的用处 四.总结 零.寒暄 这篇博客本该出现在两个月以 ...

  8. javascript中onclick事件能调用多个方法吗

    Q: javascript中onclick事件能调用多个方法吗? A: 可以的,方法如下onclick="aa();bb();cc();"每个方法用“;”分号隔开就行了

  9. js实例分析JavaScript中的事件委托和事件绑定

    我们在学习JavaScript中,难免都会去网上查一些资料.也许偶尔就会遇到“事件委托”(也有的称我“事件代理”,这里不评论谁是谁非.以下全部称为“事件委托”),尤其是在查JavaScript的事件处 ...

随机推荐

  1. Enterprise Library 3.1 参考源码索引

    http://www.projky.com/entlib/3.1/Microsoft/Practices/EnterpriseLibrary/AppSettings/Configuration/Des ...

  2. [转帖] dd 命令图解

    dd命令-->dd是disk dump的缩写,指定大小的块拷贝一个文件,同时进行指定的转换,起到一个初始化磁盘的作用  https://blog.csdn.net/jerry_1126/arti ...

  3. 如何在DBGrid中能支持多项记录的选择

    When you add [dgMultiSelect] to the Options property of a DBGrid, you give yourself the ability to s ...

  4. UVAlive3211_Now or later

    白书上的例题. 每种航班可以选择两种时间降落,如果想任意航班降落时间差的最小值最大,应该如何安排? 二分时间,如果两个时间只差小于当前枚举的时间,说明这条边不可选,可以根据2sat的方法构图. 然后判 ...

  5. BZOJ5312 冒险(线段树)

    记录区间and/or,修改时如果对整个区间影响都相同就打标记,否则递归.复杂度不太会证. #include<iostream> #include<cstdio> #includ ...

  6. VM ware 中win2008 找不到网卡驱动的解决办法之一

    在.vmx文件中用如下语句指定: ethernet0.virtualDev = "e1000" 其值为e1000指定网卡类型为Intel(R) PRO/1000(6.5默认为此项) ...

  7. MT【162】渐近估计

    (2017北大优特测试第八题) 数列 \(\{a_n\}\) 满足 \(a_1=1\),\(a_{n+1}=a_n+\dfrac{1}{a_n}\),若 \(a_{2017}\in (k,k+1)\) ...

  8. MT【119】关于恒成立的一道压轴题

    分析:处理恒成立问题,一般先代特殊值缩小范围.令x=0,则f(a)<f(0),容易知a<0. 排除答案C.容易理解a趋向于0时候,是可以的,排除D.在剩余的A,B选项里,显然偏向于A.因为 ...

  9. P3320 [SDOI2015]寻宝游戏 解题报告

    P3320 [SDOI2015]寻宝游戏 题目描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有\(N\)个村庄和\(N-1\)条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以 ...

  10. [CQOI2012] 交换棋子 (费用流)

    $pdf\space solution$    link #include<iostream> #include<cstring> #include<cstdio> ...