admin管理员组

文章数量:1317906

So I've got it to work that it shows/hides the UL's/LI's, but I'm not sure what I'm doing incorrectly where it's not swapping out the +/- signs?

Here's my 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;
});

I have a class setup to append the li with a li:before that add the + sign before the li that has the nested ul's. But I'm not sure if I am going about it the right way to swap out the signs.

Here's the fiddle that I made:

/

So I've got it to work that it shows/hides the UL's/LI's, but I'm not sure what I'm doing incorrectly where it's not swapping out the +/- signs?

Here's my 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;
});

I have a class setup to append the li with a li:before that add the + sign before the li that has the nested ul's. But I'm not sure if I am going about it the right way to swap out the signs.

Here's the fiddle that I made:

http://jsfiddle/bc4mg13a/

Share Improve this question asked Aug 21, 2014 at 17:48 ultraloveninjaultraloveninja 2,1397 gold badges34 silver badges69 bronze badges 3
  • Check stackoverflow./a/7886070/707636. Hope it'll help you to figure out the solution. – Bongs Commented Aug 21, 2014 at 17:58
  • I posted an answer, but I remend having a less verbose selector. In this case you have a class: menu-item-has-children that you can hook into such that attaching the click handler there will achieve the same effect if you instead use CSS to hide all the sub-nav ULs – Morklympious Commented Aug 21, 2014 at 18:08
  • Thanks for the replies! Yeah, it was one of those pieced together bits of code that I'm trying to integrate into a wordpress sidebar menu. – ultraloveninja Commented Aug 21, 2014 at 19:22
Add a ment  | 

7 Answers 7

Reset to default 1

There you go: http://jsfiddle/bc4mg13a/13/

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

To start with, your first js line is a has so much redundant stuff.

$(".top ul li:not(:has(li.current))").find("ul").hide().end() // Hide all other ULs .click

could be:

$(".top ul li:not(.current)").find("ul").hide().end() // Hide all other ULs .click

On the other hand, i changed your code slightly, simplified your selectors. On each li click, i select direct ul children, and the i slidetoggle + toggle class the 'current' class.

i also switch the plus sign via the current class on css.

Your code feels incredibly verbose. Well, at least your js. Here's a fiddle of your code that I modified a little bit.

Instead of hiding all your menus with js immediately on pageload, I applied a CSS display: none; to the sub-menu class:

.sub-menu {
  display: none; 
}

The js is cleaned up a bit, and since the click handler is bound to .menu-item-has-children, You're really only clicking on that to reveal the contained UL.

Give it a look. Hope it helps :)

you can just add $(this).toggleClass('open'); before you return false but I would strongly look more into what your code is doing. I'm not so sure the line before is doing anything.

Fixed 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;
});

Just added "$(this).toggleClass('open');" to use the class you specified in your CSS instead of trying to manipulate the text manually.

you can do it like this and add $(this).toggleClass('open');

http://jsfiddle/bc4mg13a/5/

For how you have it set up, I would try...

    $(".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;
});

Additional:

For formatting, you might want to do something like:

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

You don't need to use text(this.toggle ? "-" : "+");

Inside the condition, just toggle the class .open that you have already defined in your SCSS/CSS.

Like so -

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

JSFiddle

本文标签: javascriptShowHide with plus minusStack Overflow