【问题标题】:Event bound to LI is also triggered by clicks on child elements点击子元素也会触发绑定到 LI 的事件
【发布时间】: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 内的某物内。
  • 知道如何解决这个问题吗?

标签: javascript jquery dom jquery-selectors


【解决方案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 树中冒泡。”这是什么意思>_
  • 请参阅stackoverflow.com/questions/4616694/…w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html,了解有关 DOM、事件、冒泡和传播的说明。
  • 一个很好的链接来描述它!非常感谢!只有一件事,如果你停止冒泡,这意味着点击事件不会发生,对吧?
猜你喜欢
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
相关资源
最近更新 更多