点击子元素也会触发绑定到 LI 的事件
Posted
技术标签:
【中文标题】点击子元素也会触发绑定到 LI 的事件【英文标题】:Event bound to LI is also triggered by clicks on child elements 【发布时间】:2013-08-07 23:31:38 【问题描述】:我得到了以下结构:- 嵌套的 UL
<ul class="depth-one">
<li>Category 1
<ul class="depth-two">
<li > Category 1.1</li>
<li> Category 1.2</li>
<li> Category 1.3</li>
</ul>
</li>
<li> Category 2
<ul class="depth-two">
<li>Category 2.1</li>
<li>Category 2.2</li>
<li>Category 2.3</li>
</ul>
</li>
<li>Category 3
<ul class="depth-two">
<li>Category 3.1</li>
<li>Category 3.2</li>
<li>Category 3.3</li>
</ul>
</li>
</ul>
我已经用 CSS 应用了规则:
ul
list-style: none;
padding:0;
margin:0;
.depth-one
display:block;
.depth-two
display:none;
仅显示主要类别。
$(document).ready(function()
$(".depth-one > li").click(function()
selector = $(this).find(' > .depth-two');
if($(selector).css("display") == "none")
selector.slideDown(800);
else
selector.slideUp(800);
);
);
这个,在点击 MAIN 类别时切换 SUB 类别。
这里有一个小提琴来演示:http://jsfiddle.net/NB4bN/1/
现在,如您所见,当我单击 SUBCATEGORY 时,整个类别向上滑动,知道为什么吗?
我试图实现这一点,只有当我点击主类别时,子类别才会向上滑动,否则,当我点击子 <li>
项目时,什么也不会发生。
【问题讨论】:
因为点击仍在 li 内,即使它在该 li 内的某物内。 知道如何解决这个问题吗? 【参考方案1】:这里有一个解决您的问题的方法:http://jsfiddle.net/smerny/NB4bN/2/
$(document).ready(function ()
$(".depth-one > li").click(function (e)
if (e.currentTarget == e.target)
selector = $(this).find(' > .depth-two');
if ($(selector).css("display") == "none")
selector.slideDown(800);
else
selector.slideUp(800);
);
);
我添加了检查以查看 currentTarget
和 target
是否相同。所以你知道点击是在你的 li 中的一个元素上还是 li 本身。
【讨论】:
完美运行!非常感谢!如果可能的话,我想请你给我解释一下这个e.currentTarget和e.target,并没有真正理解它们的不同或它们的用法。 @kfirba 这里有几个日志语句将显示两者之间的区别:jsfiddle.net/smerny/NB4bN/4 - 你会注意到,如果你点击一个 sub-li,目标将是 sub-li而 currentTarget 将始终是与您的绑定选择器匹配的 li。 我看不出这两个调用之间有什么区别,它们都为我产生了相同的输出(控制台) 如果你点击一个 sub-li,你会得到类似 currentTarget 的东西:Category <ul class="depth-two" style="display: block;"> <li>Category 1.1</li> <li>Category 1.2</li> <li>Category 1.3</li> </ul>
和类似这样的目标:Category 1.1
基本上表明 currentTarget 是 li与您的绑定匹配,而目标是您单击的元素。
我明白了!多谢!如果你不介意,你可以看看这个小提琴:jsfiddle.net/NB4bN/5 我想做的是,如果已经显示了任何 SUB CATEGORY,并且用户选择打开另一个,它将首先关闭OPEN 子类别,然后显示用户选择的子类别【参考方案2】:
一个简单的解决方法是通过添加以下内容来停止事件冒泡:
$('li li').click(function (e)
e.stopPropagation();
);
jsFiddle example
.stoppropagation()
防止事件在 DOM 树中冒泡。因此,上面的块所做的是查找任何作为其他列表项的子项的列表项,并且每当它注册一个点击时,它就会阻止点击事件冒泡 DOM。
【讨论】:
嘿!感谢您的解决方案!我想请你解释一下你的解决方案,我不喜欢使用我不明白它的作用的代码:) 你能解释一下这个 stopPropagation() 函数的作用,以及为什么你选择li li
作为你的选择器?谢谢!
当然,答案已更新。如果您仍有疑问,请告诉我。
“防止事件在 DOM 树中冒泡。”这是什么意思>_
请参阅***.com/questions/4616694/… 和w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html,了解有关 DOM、事件、冒泡和传播的说明。
一个很好的链接来描述它!非常感谢!只有一件事,如果你停止冒泡,这意味着点击事件不会发生,对吧?以上是关于点击子元素也会触发绑定到 LI 的事件的主要内容,如果未能解决你的问题,请参考以下文章
怎么做到点击子元素(子元素自己也绑定了事件)不触发父元素绑定的事件?
H5_0038:父元素有touch事件,子元素有点击事件,如何实现点击事件