展开/收起,使用加号减号。

5

我已经让它能够显示/隐藏UL/LI,但我不确定我在哪里做错了,导致加号/减号没有交换?

这是我的JS代码:

$(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs
.click(function (e) {
if (this == e.target) {
    $(this).children('ul').slideToggle();
}
$(this).children("li.menu-item-has-children").text(this.toggle ? "-" : "+");
return false;
});

我有一个类来设置在 li 后面添加 li:before ,在具有嵌套 ul 的 li 前面添加加号。但我不确定我是否正确地交换了符号。

这是我做的 fiddle:

http://jsfiddle.net/bc4mg13a/


请查看https://dev59.com/VXI-5IYBdhLWcg3w18Z3#7886070。希望它能帮助您找到解决方案。 - Bongs
我已经发布了一个答案,但我建议使用更简洁的选择器。在这种情况下,您有一个类:menu-item-has-children,您可以将其挂钩到其中,以便如果您改为使用CSS隐藏所有sub-nav UL,则会实现相同的效果。 - Morklympious
谢谢回复!是的,这是我正在尝试集成到WordPress侧边栏菜单中的那些拼凑而成的代码之一。 - ultraloveninja
8个回答

1
你的代码感觉非常冗长,至少是JavaScript。这里是我稍微修改过的代码片段
我没有在页面加载后立即使用JavaScript隐藏所有菜单,而是将CSS display: none; 应用于子菜单类。
.sub-menu {
  display: none; 
}

JavaScript代码进行了一些清理,因为点击处理程序绑定到.menu-item-has-children,所以您只需单击该元素即可显示包含的UL。请查看,希望能有所帮助 :)

谢谢!是的,它是从我找到的一些其他代码片段拼凑而成的。所以,这是其中一种“好吧,我让这部分工作了,那另外一个呢?”对于JS来说,我觉得有一件事情就是总有不止一种方法可以实现相同的结果。 - ultraloveninja
1
当然!我认为我只是一个干净代码的粉丝。这是其中一件事情,我会审视它并问自己“我能不能让它更简洁?”因为最后我可能只是用注释来堆积代码,但我很高兴这对你有帮助 :) - Morklympious
我在想,如果其中一个li中有链接,你知道如何停止它滑动吗?我刚刚注意到并更新了fiddle。 - ultraloveninja

1

这是您需要的内容:http://jsfiddle.net/bc4mg13a/13/

$(".menu-item-has-children").on("click", function(e){
  e.stopPropagation();
  var clickedLi = $(this);
  $("> ul", clickedLi).slideToggle();
  clickedLi.toggleClass("current"); 
});

起初,你的第一行js有很多冗余的东西。 $(".top ul li:not(:has(li.current))").find("ul").hide().end() // 隐藏所有其他UL .click
可以改为: $(".top ul li:not(.current)").find("ul").hide().end() // 隐藏所有其他UL .click
另一方面,我稍微修改了你的代码,简化了选择器。在每个li点击时,我选择直接的ul子元素,然后滑动切换 'current' 类。
我还通过css中的当前类切换加号符号。

此外,stopPropagation 可以帮助避免这样的问题:如果您单击其中一个子 li,那么父级 li 也会收到事件。 - Pablo Rincon
谢谢!这个很好用,但即使加上 e.stopPropagation();,其他子项li仍然会触发 slideToggle - ultraloveninja
真的吗?我添加了stopPropagation正是为了避免发生这种情况。在我的测试中,只有点击的“+”会打开。 - Pablo Rincon
嗯,这很奇怪。是啊,无论如何它都会触发。我想知道这是否是浏览器的问题。 - ultraloveninja

0

只需添加:

$(this).toggleClass('open');

转换为这个:

if (this == e.target) {
    $(this).children('ul').slideToggle();
    $(this).toggleClass('open'); // <--
}

0

根据您的设置,我建议尝试...

    $(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs
.click(function (e) {
    if (this == e.target) {
        $(this).toggleClass("open");
        $(this).children('ul').slideToggle();
    }
    return false;
});

附加内容:

关于格式化,你可能想要做一些类似的操作:

.menu-item-has-children {
    &:before {
        content:"+ ";
        color: $white;
        width: 10px;
        display:inline-block;
    }
}
.open {
    &:before {
        content:"- ";
        color: $white;
        width: 10px;
        display:inline-block;
    }
}

0

修复JS:

$(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs
.click(function (e) {
    if (this == e.target) {
        $(this).children('ul').slideToggle();
        $(this).toggleClass('open'); // added
    }
    return false;
});

只需在代码中添加"$(this).toggleClass('open');" 来使用你在CSS中指定的类,而不是手动操作文本内容。

0

你不需要使用 text(this.toggle ? "-" : "+");

在条件语句内,只需切换你已经在你的SCSS / CSS中定义的类.open

像这样 -

$(this).toggleClass('open');

JSFiddle

{{链接1:JSFiddle}}


0

你可以在return false之前添加$(this).toggleClass('open');,但我强烈建议你更深入地了解你的代码在做什么。我不确定前面的那一行是否有任何作用。


0

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