-
DOM
事件模型
事件
HTML
元素事件是浏览器内在自动产生的
,
当有事件发生时
html
元素会向外界
(
这里主要指元素
事件的订阅者
)
发出
各种事件
,
如
click,onmou
seover,onmouseout
等等。
DOM
事件流
DOM(
文档对象模型
)
结构是一个
树型结构,当一个
HTML
元素产生一个事件时,该事件会在元
素结点与根结点之间的路径传播,
路径所经过的结点都会收到该
事件,
这个传播过程可称为
DOM
事件
流。
主流浏览器的事件模型
早在
2004
前在
H
TML
元素事件的订阅,发送,传播,处理模型上各浏览器实现并不一致,直到
DOM Level3
中规定后,多数主流浏览器才陆陆续续支持
DOM
标准的事件处理模型
—
捕获型
与冒泡型。
< br>目前除
IE
浏览器外,其它主流的
Firefox, Opera, Safari
都支持标准的
DOM
事件处理模型。
IE
仍
然使用自己的模型,即冒泡型,它模型的一部份被
DOM
采用,这点对于开发者来说也是有好处
的,只使用
D
OM
标准,
IE
都共有的事件处理方式
才能有效的跨浏览器。
冒泡型事件
(Bubbling)
<
/p>
这是
IE
浏览器对事件模型的实现,也是
最容易理解的,至少笔者觉得比较符合实际的。冒泡,
顾名思义,事件像个水中的气泡一
样一直往上冒,直到顶端。从
DOM
树型结构上理解,就是事<
/p>
件由叶子结点沿祖先结点一直向上传递直到根结点;从浏览器界面视图
HTML
元素排列层次上
理解就是事件由具有从属关系的最
确定的目标元素一直传递到最不确定的目标元素
.
捕获型事件
(Capturing)
Netscape Navigator
的实现,它与冒泡型刚
好相反,由
DOM
树最顶层元素一直到最精确的元素,
这个事件模型对于开发者来说(至少是我
..
)
有点费解,因为直观上的理解应该如同冒泡型,事
件传递应该由最确定的元素,即事件产
生元素开始。
但这个模型在某些情况下也是很有用的,接下来会讲解到。
DOM
标准事件模型
因为两个不同的模型都有其优点和解释,
DOM
标准支
持捕获型与冒泡型,可以说是它们两者的
结合体。它可以在一个
DOM
元素上绑定多个事件处理器,并且在处理函数内部,
th
is
关键字仍
然指向被绑定的
DOM<
/p>
元素,另外处理函数参数列表的第一个位置传递事件
event<
/p>
对象。
首先是捕获式传递事件,
接着是冒泡式传递,
所以,
如果一个处理函数
既注册了捕获型事件的监
听,又注册冒泡型事件监听,那么在
D
OM
事件模型中它就会被调用两次。
注册与移除事件监听器
注册事件监听
器,
或又称订阅事件,
当元素事件发生时浏览器回调该监听函数
执行事件处理。
目
前主流浏览器中有两种注册事件的方法,一种
是
IE
浏览器的,另一种是
DOM
p>
标准的。
1.
直
接
JS
或
HTML
挂载法
onclick
=
>
element.
onclick
=
function
(){
alert
(
this
.
innerHTML
)
;
}
移除时将事件属性设
为
nul
即可,这个也是最常用的方法了,优缺点也是显然的:
?
?
?
?
简单方便,在
HTML
中直接书写处理函数的代码块,在
JS
中给元素对应事件属性赋值
即可
IE
与
DOM
标准都支持的一
种方法,
它在
IE
与
< br>DOM
标准中都是在事件冒泡过程中被调
用的。
可以在处理函数块内直接用
this
引用注册事件的元素
要给元素注册多个监听器,就不能用这方法了
2.
IE
下注册多个事件监听器与移除监听器方法
IE
浏览器中
HTML
元素有
个
attachEvent
方法允许外界注册该元素多个事件监
听器
,
例如
element.
attachEvent
(
< br>'onclick'
,
observer
)
;
attachEvent
接受两个参数。第一个参数是事件名称,
第二个参数
observer
是回调处理函数。<
/p>
这里
得说明一下,有个经常会出错的地方,
IE
下利用
attachEvent
注册的处理函数调用时
this
指向不
再是先前注册事件的元素,这时的
this
为
< br>window
对象了,笔者很奇怪
IE
< br>为什么要这么做,完
全看不出好处所在。
要移除先前注册的事件的监听器
,
调用
element
的
detachEvent
方法即可,参数相同。
elemen
t.
detachEvent
(
'on
click'
,
observer
)
;
3.
DOM
标准下注册多个事件监听器与移除监听器方法
实现
DOM
标准的浏览器与
IE
浏览器中注册元素事件监听器方式有所不同,它通过元素的
addEventListener
方法注册,该方法既支持注册冒泡型事件处理,
又支持捕获型事件处理。
element.
addEventListener
(
'click
'
,
observer
,
useCapture
)
;
addEventListener
方法接受三个参数。第一个参数是事
件名称,值得注意的是,这里事件名称与
IE
的不同,事件名称
是没
’on’
开头的
;
第二个参数
observer
是回调处理函数
;
第三个参数注明该处
理回调函数是在事件传递
过程中的捕获阶段被调用还是冒泡阶段被调用
移除已注册的事
件监听器调用
element
的
rem
oveEventListener
即可,参数不变
.
element.
removeEventListene
r
(
'click'
,
observer
,
useCapture
)
;
跨浏览器的注册与移除元素事件监听器方案
< br>弄清楚
DOM
标准与
IE
的注册元素事件监听器之间的异同后,就可以实现一个跨浏览器的注册
与移除元素事件监听器方案
:
//
注册
function
addEventHandler
(
element
,
evtName
,
callback
,
useCapture
)
{
//DOM
标准
if
(
el
ement.
addEventListener
)
{
element.
addEventListener
(
evtName
,
callback
,
useCapture
)
;
}
else
{
//IE
方式
,
忽略
useCapture
p>
参数
element.
< br>attachEvent
(
'on'
+
evtName
,
callback
)
;
}
}
//
移除
//
注册
function
removeEventHandler<
/p>
(
element
,
evtName
,
callback
,
useCapture
)
{
//DOM
标准
if
(
el
ement.
removeEventListener
)
p>
{
eleme
nt.
removeEventListener
(
evtName
,
callback
,
useCapture
)
;
}
else
{
//IE
方式
,
忽略
useCapture
p>
参数
element.
< br>dettachEvent
(
'on'
< br>
+
evtName
,
callback
)
;
}
}
如何取消浏览器事件的传递与事件传递后浏览器的默认处理
<
/p>
先说明取消事件传递与浏览器事件传递后的默认处理是两个不同的概念,
< br>可能很多同学朋友分不
清,或者根本不存在这两个概念。
取消事件传递是指,
停止捕获型事件或冒泡型事件的进一步传递
。
例如上图中的冒泡型事件传递
中,
在
body
处理停止事件传递后,
位于上
层的
document
的事件监听器就不再收到通知,
不再被
处理。
事件传
递后的默认处理是指,
通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作
(如果存在这样的动作)。例如,如果表单中
input
type
属性是
“submit”
,点击后在事件传播完
浏览器就就自动提交表单。又例如,
p>
input
元素的
keydown
事件发生并处理后,浏览器默认会
将用户键入的字符自动追加到
input
元素的值中。
要取消浏览器的件传递
,IE
与
DOM
标准又有所不同。
在
IE
下
,
通过设置
even
t
对象的
cancelBubble
为
true
即可。
function
someHandle
()
{
window.
< br>event
.
cancelBubble
=
true
;
}
DOM
标
准通过调用
event
对象的
stop
Propagation()
方法即可。
function
someHa
ndle
(
event
)
{
event.
stopPropagation
()
;
p>
}
因些,跨浏览器的停止事件传递的方法是
:
function
someHa
ndle
(
event
)
{
event
=
event
||
window.
event
;
if
(
event.
stopPropagation
)
event.
stopPropagation
()
;
else
event.
cancelBubble
=
true
;
}
取消事件传递后的默认处理,
p>
IE
与
DOM
标准
又不所不同。
在
IE
下
,
通过设置
event
p>
对象的
returnValue
为
false
即可。
function
someHandle
()
{
window.
< br>event
.
returnValue
< br>
=
false
;
}
DOM
标
准通过调用
event
对象的
prev
entDefault()
方法即可。
function
someHa
ndle
(
event
)
{
event.
preventDefault
()
;
}
因些,跨浏览器的取消事件传递后的默认处理方法是:
function
someHa
ndle
(
event
)
{
event
=
event
||
window.
event
;
if
(
event.
preventDefault
)
e
vent.
preventDefault
()
;
else
event.
returnValue
=
false
;
}
捕获型事件模型与冒泡型事件模型的应用场合
标准事件模型为我们提供了两种方案,
可能很多朋友分不清这两种不同模型有啥
好处,
为什么不
只采取一种模型。
<
/p>
这里抛开
IE
浏览器讨论(
IE
只有一种,没法选择)什么情况下适合哪种事件模型。
< br>
1.
捕获型应用场合
p>
捕获型事件传递由最不精确的祖先元素一直到最精确的事件源元素,
传递方式与操作系统中的全
局快捷键与应用程序快捷键相似。
当
一个系统组合键发生时,
如果注册了系统全局快捷键监听器,
该
事件就先被操作系统层捕获,
全局监听器就先于应用程序快捷键监听器得到通知,
也就是全局
的先获得控制权,
它有权阻止事件
的进一步传递。
所以捕获型事件模型适用于作全局范围内的监
听
,这里的全局是相对的全局,相对于某个顶层结点与该结点所有子孙结点形成的集合范围。
例如你想作全局的点击事件监听,
相对于
< br>document
结点与
document
下所有的子结点,
在某个条
件下要求所有的子结点点
击无效,
这种情况下冒泡模型就解决不了了,
而捕获型却非常适
合,
可
以在最顶层结点添加捕获型事件监听器,伪码如下
:
function
globalClickListener
(
event
)
{
if
(
canEventPass
==
false
)
{
//
取消
事件进一步向子结点传递和冒泡传递
event.
stopPropagation
()
;
//
取消浏览器事件后的默认执行
<
/p>
event.
preventDefault
()
;
}
}
p>
这样一来,当
canEventPass
条
件为假时,
document
下所有的子结点
< br>click
注册事件都不会被浏览
器处理。
2.
冒泡型的应用场合
可以说我们平时用的都是冒泡事件模型,因为
IE
只支持这模型。这里还是说说,在恰当利用该
模型可以提高脚本性能。在元素
一些频繁触发的事件中,如
onmousemove,
onm
ouseover,onmouseout,
如果明确事件处理后没必要进一步传递,那
么就可以大胆的取消它。此
外,
对于子结点事件监听器的处理会
对父层监听器处理造成负面影响的,
也应该在子结点监听器
中禁
止事件进一步向上传递以消除影响。
综合案例分析
最后结合下面
HTML
代码作分析
:
id
=
p>
onclick
=
>
id
=
p>
onclick
=
>
id
=
p>
onclick
=
>
id
=
p>
style
=
re
d;
onclick
=
>
HTML
运行后点击红色区域
,
这是最里层的
DIV,
根据上面说明
,
无论
是
DOM
标准还是
IE,
直接写
在
html
里的监听
处理函数是事件冒泡传递时调用的
,
由最里层一直往上传递
p>
,
所以会先后出现
current is event_source
current is div2
current is
div1
current is div0
current
is body
添加以下片段
:
var
div2
=
document.
getEle
mentById
(
'div2'
)<
/p>
;
addEventHandler<
/p>
(
div2
,
'click'
,
< br>function
(
event
){
event
=
event
||
window.
event
;
if
(
event.
stopPropagation
)
event.
stopPropagation
()
;
else
event.
cancelBubble
=
true
;
}
,
fal
se
)
;
当
点击红色区域后
,
根据上面说明
,
p>
在泡冒泡处理期间
,
事件传递到
div2
后被停止传递了
,
所以
div2
上层的元素收不到通知
,
所以会先后出现
:
-
-
-
-
-
-
-
-
-
上一篇:2020初中语文基础知识归纳+实战演练-第一章:字音字形
下一篇:盘点制度
DOM 事件模型的相关文章
-
余华爱情经典语录,余华爱情句子
余华的经典语录——余华《第七天》40、我不怕死,一点都不怕,只怕再也不能看见你——余华《第七天》4可是我再也没遇到一个像福贵这样令我难忘的人了,对自己的经历如此清楚,
-
心情低落的图片压抑,心情低落的图片发朋友圈
心情压抑的图片(心太累没人理解的说说带图片)1、有时候很想找个人倾诉一下,却又不知从何说起,最终是什么也不说,只想快点睡过去,告诉自己,明天就好了。有时候,突然会觉得
-
经典古训100句图片大全,古训名言警句
古代经典励志名言100句译:好的药物味苦但对治病有利;忠言劝诫的话听起来不顺耳却对人的行为有利。3良言一句三冬暖,恶语伤人六月寒。喷泉的高度不会超过它的源头;一个人的事
-
关于青春奋斗的名人名言鲁迅,关于青年奋斗的名言鲁迅
鲁迅名言名句大全励志1、世上本没有路,走的人多了自然便成了路。下面是我整理的鲁迅先生的名言名句大全,希望对你有所帮助!当生存时,还是将遭践踏,将遭删刈,直至于死亡而
-
三国群英单机版手游礼包码,三国群英手机单机版攻略
三国群英传7五神兽洞有什么用那是多一个武将技能。青龙飞升召唤出东方的守护兽,神兽之一的青龙。玄武怒流召唤出北方的守护兽,神兽之一的玄武。白虎傲啸召唤出西方的守护兽,
-
不收费的情感挽回专家电话,情感挽回免费咨询
免费的情感挽回机构(揭秘情感挽回机构骗局)1、牛牛(化名)向上海市公安局金山分局报案,称自己为了挽回与女友的感情,被一家名为“实花教育咨询”的情感咨询机构诈骗4万余元。