说我的结构如下:
<ul id="a">text
<li id="b">text</li>
<li id="c">text</li>
</ul>
如何为a,b和c分配不同的事件处理程序(比如onclick listener)?当我将处理程序分配给<ul>
时,会在点击任何<li>
时触发。
答案 0 :(得分:3)
而不是为列表中的每个元素设置单个处理程序,最好在父级上使用单个事件侦听器,并使用事件委托检测哪个是用户单击的元素的id
$('ul').on('click', function(evt) {
id = evt.target.id;
switch (id) {
"a" : ... break;
"b" : ... break;
"c" : ... break;
default: ... ;
}
});
答案 1 :(得分:2)
每当一个事件被触发时,它就会“起泡”。这意味着它在与它相关联的实际元素上被调用,但它也为链中的每个父元素一直触发到顶部。因此,在您的情况下,只要您点击b
或c
,该事件也会为a
触发。为避免这种情况,您需要停止冒泡。
具体来说,在b和c的事件处理程序中,你应该通过这样做来停止事件冒泡:
if (event.stopPropagation) event.stopPropagation();
else event.cancelBubble = true;
大多数浏览器都支持事件stopPropagation
以结束冒泡。旧版本的IE使用cancelBubble
属性。所以上面应该是跨浏览器兼容的。
我知道你没有指定jQuery,但由于它如此受欢迎,值得注意的是,如果你使用jQuery,这个条件隐藏在框架后面,所以你可以这样做:
event.stopPropagation()
答案 2 :(得分:1)
每个事件都会在DOM树中冒泡(或者至少“应该”,因为有IE)。您可能想停止冒泡,请参阅Ben Lee's answer。但有更好的方法:
只需检查触发您的侦听器的事件是否针对您正在观看的元素被触发。然后执行你的处理程序,或者转义。
document.getElementById("a").addEventListener("click", function(e) {
var a = e.currentTarget; // reference to #a
var t = e.target; // this may be #b or #c or any of their children - or not
if (a != t)
return;
// else
// do what you wanted to do
}, false);
答案 3 :(得分:0)
你可以使用它。
$('ul li#a').click(function(){
//some thing here...
});
$('ul li#b').click(function(){
//some thing here...
});
答案 4 :(得分:0)
我的一个项目中也遇到了同样的问题。我所做的是首先声明一个全局变量(用于标记目的,默认值为false)。然后我触发了所有子节点上的onmouseover和onmouseout事件,并且每当光标在子节点上时将标志值更改为true(并且每当它离开子节点时将其恢复为false)。因此,在声明父级的onclick函数时,只需输入一个条件来检查flag的值。