【问题标题】:Nested navigation click logic issue嵌套导航点击逻辑问题
【发布时间】:2014-10-14 23:05:15
【问题描述】:

我一直在尝试获得一个简单的垂直导航,以便在单击时显示列表项的子项。

但是,当您随后单击任何嵌套的子列表项时,您实际上是在再次“单击”父列表项。这会触发我的点击功能以删除“.active”并在用户被重定向到他们选择的页面之前关闭父列表项。这看起来很糟糕,而且非常烦人。

关于如何获得不影响子列表项的点击功能有什么建议吗?

$('#sidebar > li.parent').click(function(){
  if($(this).hasClass('active')){
        $(this).removeClass('active');
      }else{
        $(this).addClass('active');
  }
});

HTML

<aside id="tertiary" class="tertiary">
    <ul id="sidebar" class="sidebar">
        <li class="active"><a href="/">Portal</a></li>
        <li><a href="ecards.html">Start Here</a></li>
        <li><a href="ecards.html">Cards</a></li>
        <li class="parent"><a href="programs.html">Programs</a>
            <ul>
                <li><a href="#">LOS</a></li>
                <li><a href="#">Safety</a></li>
                <li><a href="#">Retirement</a></li>
                <li><a href="#">Wellness</a></li>
                <li><a href="#">Investors</a></li>
            </ul>
        </li>
        <li><a href="#">Marketplace</a></li>
        <li><a href="#">Reporting</a></li>
    </ul>
</aside>

【问题讨论】:

  • 添加return false 或使用.stopPropagation() 并将其绑定到孩子。
  • @j08691: return false 也会阻止链接工作。
  • @TrueBlueAussie - 您确实看到子链接只是 #?
  • @j08691:是的......你会阻止那些bookmark链接工作:)

标签: javascript jquery html css


【解决方案1】:

您需要停止在子代中传播...而不是父代

http://jsfiddle.net/TrueBlueAussie/g6a496Lf/

$('#sidebar > li.parent').click(function (e) {
    e.preventDefault();
    $(this).toggleClass('active');
}).find("ul li").click(function(e){
    e.stopPropagation();    
});

e.preventDefault() 只是用于阻止链接单击示例中的父级。 e.stopPropagation() 阻止子点击冒泡 DOM。

我将两个处理程序链接在一起,因此您不需要像这样的单独选择器:

$('#sidebar > li.parent ul li").click(function(e){
    e.stopPropagation();    
});

【讨论】:

  • 第一个 e.preventDefault 破坏了初始点击功能。
  • @BenRacicot:因此说这只是为了举例...... 拿出来 :)
  • 啊,很好。谢谢你的回答。
【解决方案2】:

您可以为使用stopPropagation 的子元素添加点击处理程序,以防止点击事件冒泡到父元素:

$('#sidebar > li li').click(function(e){
  e.stopPropagation();
});

延伸阅读:MDN docs for Event.

【讨论】:

  • 您需要停止在子代中传播...而不是父代
  • 嗯,这对我来说是一个新概念。我将如何停止对孩子的传播?
  • 此时此解决方案可能适用于您,但我会认真考虑查看下面的答案以及随附的解释链接。我还包括一个小提琴,以证明它按预期工作。
【解决方案3】:

在停止传播事件之前,请花一些时间在 why you shouldn't do so 上启动。

来自 css-tricks.com,“停止事件传播的危险”,非常简要:

“修改一个单一的、稍纵即逝的事件一开始似乎无害,但它会带来风险。当你改变人们期望的行为以及其他代码所依赖的行为时,你就会有错误。这只是一个问题时间。”

“更好的解决方案是使用一个事件处理程序,其逻辑完全封装,其唯一职责是确定是否应为给定事件隐藏菜单。”

话虽如此,你可以做类似的事情

$('#sidebar').on('click', function( e ) {
    var $target = $(e.target).closest('li');

    if ( $target.hasClass('parent') ) {
        $target.toggleClass('active');
    }
});

工作示例: http://jsfiddle.net/g6a496Lf/1/

【讨论】:

  • 你的链接已经失效(至少从这里开始):( 最好在工作时复制一些相关内容。
  • @TrueBlueAussie 我已经尝试了几次,它对我有用,但我会添加内容...谢谢!
猜你喜欢
  • 2016-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
相关资源
最近更新 更多