Search code examples
jquerytoggleclass

JQuery toggleClass parent and children


I'm just getting to know Javascript and JQuery and I can't figure this out: Is there a shorter way for this:

$(".toggle").click(function(){
$(this).parent().toggleClass("collapsed");
$(this).parent().children().toggleClass("collapsed");
$(this).parent().next(".abcContent").toggle(0);

I'm glad I got it to work after all but surely this isn't how it's done properly... I want to toggle the parent class (abcTitle) including its children (i.e. button).

<div class="abcTitle">
<div class="abcButton toggle"></div>
<h4 class=toggle>Title</h4><div class="sortable"></div>
</div>
<div class="abcContent">Content</div>

Thanks for enlightening me!

For clarification here's some relevant CSS

.abcButton {
    background-image:url(minus.png);
}
.abcButton.collapsed {
    background-image:url(plus.png); 
}
.abcTitle {
    border-top-left-radius:14px;
}
.abcTitle.collapsed {
    border-bottom-left-radius:14px;
}

So basically a click on either abcButton or H4 is supposed to trigger the collapse of abcContent while adding class .collapsed to both abcButton and abcTitle.
(Btw, If I could figure out how to exclude

<div class="sortable"></div>

from the click function I could just make abcTitle my click handler with no need to seperate abcButton and h4)


Solution

  • You should cache, or chain, your jQuery object; $(this).parent() is being calculated 3 times.

    $(".toggle").click(function(){
        var self = $(this).parent();
    
        self.toggleClass("collapsed");
        self.children().toggleClass("collapsed");
        self.next(".abcContent").toggle(0);
    

    You shouldn't need to add the collapsed class to your children elements; you CSS should work out that the elements are collapsed from the fact the parent has the class of collapsed.

    div.abcTitle h4 {
        /* Styles when the element is shown */
    }
    
    div.abcTitle.collapsed h4 {
        /* Styles when the element is collapsed */
    }
    

    You can probably guarantee that the next element will always be the abcContent, so you shouldn't need to worry about selecting the next element.

    If you are toggling a number of elements, it'll be better to use the delegate or live methods, which utilize the event bubbling mechanisms of JavaScript; the event handler is only bound to one element, rather than all of them, increasing performance.

    Having said all of that, a better solution might be as follows:

    $(document).delegate('.toggle', 'click', function () {
        $(this).parent().toggleClass('collapsed').next().toggle();
    });