今天在写一个项目中遇到了一个问题,用js控制一个div的显示和隐藏。本来想着挺简单的,结果就遇到了让我比较郁闷的事情了。不管我怎么改就是没有效果。绞尽脑汁的查找,终于在快下班的时候找到了问题所在。我的HTML是这样子的:
类型
点击类
skin-series弹框出现,点击取消弹框隐藏。大家都知道,事件在执行时会先执行事件捕获然后是事件冒泡。因为我点击取消隐藏了弹框,可是当事件流传到
类
skin-series时又执行了显示,所以没有达到想要的效果。添加一个
event
.
stopPropagation
()
;
//阻止事件冒泡
就可以到达想要的效果了,nice!
$
(
'
.cancel-btn
'
)
.
click
(
function
(
event
){
event
.
stopPropagation
()
;
//阻止事件冒泡
$
(
'
.skin-choose-box
'
)
.
hide
()
;
}
)
;
////////////////////////////////////////////////////////
下面我想写写在js中以及各个浏览器事件流之间的区别:
目前除IE浏览器外,其它主流的Firefox, Opera, Safari都支持标准的DOM事件处理模型。IE仍然使用自己的模型,即冒泡型,它模型的一部份被DOM采用,这点对于开发者来说也是有好处的,只使用DOM标准,IE都共有的事件处理方式才能有效的跨浏览器。
DOM标准事件模型
因为两个不同的模型都有其优点和缺点,DOM标准支持捕获型与冒泡型,可以说是它们两者的结合体。它可以在一个DOM元素上绑定多个事件处理器,并且在处理函数内部,this关键字仍然指向被绑定的DOM元素,另外处理函数参数列表的第一个位置传递事件event对象。
1.在HTML中直接书写处理函数的代码块,在JS中给元素对应事件属性赋值即可,IE与DOM标准都支持的一种方法,它在IE与DOM标准中都是在事件冒泡过程中被调用的。可以在处理函数块内直接用this引用注册事件的元素
,要给元素注册多个监听器,就不能用这方法了
2. IE下注册多个事件监听器与移除监听器方法
IE浏览器中HTML元素有个attachEvent方法允许外界注册该元素多个事件监听器,例如
element.attachEvent(
'onclick'
, observer);
attachEvent接受两个参数。第一个参数是事件名称,第二个参数observer是回调处理函数。这里得说明一下,有个经常会出错的地方,IE下利用attachEvent注册的处理函数调用时this指向不再是先前注册事件的元素,这时的this为window对象了。
要移除先前注册的事件的监听器,调用element的detachEvent方法即可,参数相同。
element.detachEvent(
'onclick'
, observer);
3. DOM标准下注册多个事件监听器与移除监听器方法:
实现DOM标准的浏览器与IE浏览器中注册元素事件监听器方式有所不同,它通过元素的addEventListener方法注册,该方法既支持注册冒泡型事件处理,又支持捕获型事件处理。
element.addEventListener('click'
, observer, useCapture);
addEventListener方法接受三个参数。第一个参数是事件名称,值得注意的是,这里事件名称与IE的不同,事件名称是没’on’开头的;第二个参数observer是回调处理函数;
第三个参数注明该处理回调函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用。
移除已注册的事件监听器调用element的removeEventListener即可,参数不变.
element.removeEventListener('click'
, observer, useCapture);
跨浏览器的注册与移除元素事件监听器方案,弄清楚DOM标准与IE的注册元素事件监听器之间的异同后,就可以实现一个跨浏览器的注册与移除元素事件监听器方案:
//注册
function
addEventHandler
(
element
,
evtName
,
callback
,
useCapture
)
{
//DOM标准
if
(
element
.
addEventListener
)
{
element
.
addEventListener
(
evtName
,
callback
,
useCapture
)
;
}
else
{
//IE方式,忽略useCapture参数
element
.
attachEvent
(
'
on
'
+
evtName
,
callback
)
;
}
}
//移除
function
removeEventHandler
(
element
,
evtName
,
callback
,
useCapture
)
{
//DOM标准
if
(
element
.
removeEventListener
)
{
element
.
removeEventListener
(
evtName
,
callback
,
useCapture
)
;
}
else
{
//IE方式,忽略useCapture参数
element
.
dettachEvent
(
'
on
'
+
evtName
,
callback
)
;
}
}
如何取消浏览器事件的传递与事件传递后浏览器的默认处理:
取消事件传递是指,停止捕获型事件或冒泡型事件的进一步传递。例如上图中的冒泡型事件传递中,在body处理停止事件传递后,位于上层的document的事件监听器就不再收到通知,不再被处理。
事件传递后的默认处理是指,通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作)。例如,如果表单中input type 属性是 “submit”,点击后在事件传播完浏览器就就自动提交表单。又例如,input 元素的 keydown 事件发生并处理后,浏览器默认会将用户键入的字符自动追加到 input 元素的值中。
要取消浏览器的件传递,IE与DOM标准又有所不同。
在IE下,通过设置event对象的cancelBubble为true即可。
function
someHandle
()
{
window
.
event
.
cancelBubble
=
true
;
}
DOM标准通过调用event对象的stopPropagation()方法即可。
function
someHandle
(
event
)
{
event
.
stopPropagation
()
;
}
因些,跨浏览器的停止事件传递的方法是:
function
someHandle
(
event
)
{
event
=
event
||
window
.
event
;
if
(
event
.
stopPropagation
)
{
event
.
stopPropagation
()
;
}
else
{
event
.
cancelBubble
=
true
;
}
}
取消事件传递后的默认处理,IE与DOM标准又不所不同。
在IE下,通过设置event对象的returnValue为false即可。
function
someHandle
()
{
window
.
event
.
returnValue
=
false
;
}
DOM标准通过调用event对象的preventDefault()方法即可。
function
someHandle
(
event
)
{
event
.
preventDefault
()
;
}
因些,跨浏览器的取消事件传递后的默认处理方法是:
function
someHandle
(
event
)
{
event
=
event
||
window
.
event
;
if
(
event
.
preventDefault
)
{
event
.
preventDefault
()
;
}
else
{
event
.
returnValue
=
false
;
}
}