JS的事件传播,以前完全不知道,今天学习了。
JS的事件(event)是向上传播的,会一直传到根元素。
比如(使用jquery语法):
- $("div").click(function(event) {
- alert("div clicked");
- });
- $("span").click(function(event) {
- alert("span clicked");
- });
$("div").click(function(event) {
alert("div clicked");
});
$("span").click(function(event) {
alert("span clicked");
});
span是div的子元素,在点击span的时候,span的click事件向上传播到div的onclick函数里,所以画面会先后弹出“span clicked"和“div clicked”。
如果不想让事件向上传播,有以下几种办法。
1.return false;
- $("div").click(function(event) {
- alert("div clicked");
- });
- $("span").click(function(event) {
- alert("span clicked");
- returnfalse;
- });
$("div").click(function(event) {
alert("div clicked");
});
$("span").click(function(event) {
alert("span clicked");
return false;
});
在span的事件函数里return false,就能阻止span的click事件传到div的onclick函数。
2.调用event.target进行判断
- $("div").click(function(event) {
- if (event.target == this)
- alert("div clicked");
- });
- $("span").click(function(event) {
- alert("span clicked");
- returnfalse;
- });
$("div").click(function(event) {
if (event.target == this)
alert("div clicked");
});
$("span").click(function(event) {
alert("span clicked");
return false;
});
event.target是事件发生源的DOM元素。在span的onclick函数里,event.target和this一样,都是span元素;而在div的onclick函数里,event.target是span元素,this是div元素。
3.event.stopPropagation();
- $("div").click(function(event) {
- alert("div clicked");
- });
- $("span").click(function(event) {
- alert("span clicked");
- event.stopPropagation();
- });
$("div").click(function(event) {
alert("div clicked");
});
$("span").click(function(event) {
alert("span clicked");
event.stopPropagation();
});
在子元素的事件函数里调用event.stopPropagation();。
注意:虽然event.target和event.stopPropagation()是纯DOM API,但不是被所有浏览器实现了的。jquery对这两个API做了统一,所有浏览器中都能使用。
当然,事件向上传播也有他的作用。
比如一个需要highlight的例子,有一个按钮区(DIV),里面有很多个按钮(BUTTON),这些元素都是白色。当鼠标移动到DIV时,DIV需要显示成浅灰色,BUTTON们还是白色,接着再移到BUTTON上时,DIV保持浅灰色,BUTTON要变成深灰色。
实现方式是给DIV和每个BUTTON都注册一对onmouseover/onmouseout事件函数,鼠标从按外进入DIV内时,触发DIV的onmouseover,DIV变灰,鼠标再移到DIV内某个BUTTON上时,触发DIV的onmouseout,DIV恢复成白色,这时BUTTON触发了onmouseover而变深灰,而且这个mouseover的event向上传播到了DIV触发了DIV的onmouseover,DIV又变灰,效果就是,当鼠标从DIV移到BUTTON上进,DIV保持灰色。假想一下,如果这个时候DIV没有保持灰色而变回了白色,效果就会很怪。也就是说,这个时候就需要事件上传机制把BUTTON这个子元素的mouseover event上传给DIV。
再举个例子,一个table有1000个row,每个row都要注册一个onclick函数,为每个row注册事件函数写起来容易,但由于循环多和有太多的函数需要内存管理,效率会下降。这个时候就可以写一个单一的事件函数,处理row的父元素,所有row的click event都会向上传播到这个事件函数里来接受处理。1000个事件函数需要注册和管理,现在变成一个,效率自然提升很多。