点击子元素也会触发绑定到 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 时,整个类别向上滑动,知道为什么吗?

我试图实现这一点,只有当我点击主类别时,子类别才会向上滑动,否则,当我点击子 &lt;li&gt; 项目时,什么也不会发生。

【问题讨论】:

因为点击仍在 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);
            
        
    );
);

我添加了检查以查看 currentTargettarget 是否相同。所以你知道点击是在你的 li 中的一个元素上还是 li 本身。

【讨论】:

完美运行!非常感谢!如果可能的话,我想请你给我解释一下这个e.currentTarget和e.target,并没有真正理解它们的不同或它们的用法。 @kfirba 这里有几个日志语句将显示两者之间的区别:jsfiddle.net/smerny/NB4bN/4 - 你会注意到,如果你点击一个 sub-li,目标将是 sub-li而 currentTarget 将始终是与您的绑定选择器匹配的 li。 我看不出这两个调用之间有什么区别,它们都为我产生了相同的输出(控制台) 如果你点击一个 sub-li,你会得到类似 currentTarget 的东西:Category &lt;ul class="depth-two" style="display: block;"&gt; &lt;li&gt;Category 1.1&lt;/li&gt; &lt;li&gt;Category 1.2&lt;/li&gt; &lt;li&gt;Category 1.3&lt;/li&gt; &lt;/ul&gt; 和类似这样的目标: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事件,子元素有点击事件,如何实现点击事件

mouseover和mouseout事件在鼠标经过子元素时也会触发

如何阻止子元素触发父元素的事件

jquery 点击事件

a子元素中,其中一个绑定点击事件,点击其他子元素进行页面跳转。当点击这个子元素,怎么阻止a标签跳转。