jQuery 扩展导航,在子元素点击时折叠

4

https://jsfiddle.net/aesya0g6/

你好!

我已经创建了一个可以展开的导航菜单,它运行得非常好,但是子菜单的点击会导致它折叠。我尝试过更改jQuery指向的位置,以期望解决这个问题,但没有成功。我错在哪里了?

    $('.expandingNav').click(function(){
  if($(this).hasClass('expanded')){
    $(this).children('.hidden').slideUp();
    $(this).removeClass('expanded');
  }
  else{
    $(this).children('.hidden').slideDown();
    $(this).addClass('expanded');
  }
});
5个回答

2
您可以检查最近的ul元素是否有一个父级元素为nav.sidebar:
$('.expandingNav').on('click', function (e) {
    if ($(e.target).closest('ul').parent('nav.sidebar').length) {
        // ...
    }
});

Updated Example

$('.expandingNav').on('click', function (e) {
    if ($(e.target).closest('ul').parent('nav.sidebar').length) {
        if ($(this).hasClass('expanded')) {
            $(this).children('.hidden').slideUp();
            $(this).removeClass('expanded');
        } else {
            $(this).children('.hidden').slideDown();
            $(this).addClass('expanded');
        }
    }
});

或者,您还可以检查父元素的下一个兄弟元素是否为 ul 元素:
$('.expandingNav').on('click', function (e) {
    if ($(e.target).parent().next('ul').length) {
        // ...
    }
});

Updated Example

$('.expandingNav').on('click', function (e) {
    if ($(e.target).parent().next('ul').length) {
        if ($(this).hasClass('expanded')) {
            $(this).children('.hidden').slideUp();
            $(this).removeClass('expanded');
        } else {
            $(this).children('.hidden').slideDown();
            $(this).addClass('expanded');
        }
    }
});

那个完美地运行了!然而,新手问题,e是什么时候被定义的?我正在努力熟悉JS和jQuery,并且我自己编写了所有这些的第一部分,但是像e这样的东西出现了,我又感到迷失了。 - user3888851
click 事件监听器中,e 代表 'event'。你可以随意命名这个变量,它在这里是一个参数.. $('.expandingNav').on('click', function (e) { ... });。如果你查看 click 方法的文档,你会发现该对象被称为 "eventData" .. http://api.jquery.com/click/ - Josh Crozier
文档有点混乱 - 请澄清,e始终是点击的数据吗?除了e.target,我还可以传递哪些其他内容给e? - user3888851
@user3888851 实际上,e 只是与点击事件相关联的事件对象。要查看所有其他属性,您可以记录 e 并查看。console.log(e) - Josh Crozier

1
您可以通过添加以下内容来简单实现它:

//If the e.target is the same element as this, you've not clicked on a descendant.
if( e.target !== this ) return;

更新的fiddle


@JoshCrozier 您是正确的,如果UI能够做出一点让步,那么这将是一个简单的方法。当然,您的方式更好,我也投票支持您提供的答案。 - huan feng

0
当您单击一个项目的子项时,单击事件会“冒泡”到其父级,从而触发单击事件,导致向上滑动。 您应该处理子项上的单击事件,并使用stopPropagation来避免事件冒泡。 尝试像这样做:
$('.expandingNav li').click(function(ev) { ev.stopPropagation(); })

0

在这种情况下,您应该避免在您点击的元素内传播任何东西,例如 expandingNav 类内的 li 元素。

   $("li.expandingNav").on('click', function(e) {
  if($(this).hasClass('expanded')){
    $(this).children('.hidden').slideUp();
    $(this).removeClass('expanded');
  }
  else{
    $(this).children('.hidden').slideDown();
    $(this).addClass('expanded');
  }
    });
//On sub LI click , stop propagating. 
$("li.expandingNav li").on('click', function(e) {
 e.stopPropagation();
}); 

工作的Fiddle


0

不要让混乱的额外代码困扰自己。

只需将监听器放在a标签上。

像这样:

  $('.expandingNav').children('a').click(function(){
   var element = $(this).parent();
  if($(element).hasClass('expanded')){
    $(element).children('.hidden').slideUp();
    $(element).removeClass('expanded');
  }
  else{
    $(element).children('.hidden').slideDown();
    $(element).addClass('expanded');
  }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接