Search code examples
javascriptjqueryelementslidetoggletoggleclass

How to close other open elements when one is opened in jQuery?


I know. The title was a bit....hard to understand. I will see what I can do to help you understand it.

Basically, what I've done for my personal site is the main navigation as the body of the web page. And when a link is clicked, it loads some hidden content, like so:

    $(document).ready(function(){
    $('li a#about-toggle').click(function(){
        $('li#about').animate({"height": "toggle", "opacity": "toggle"}, "slow").toggleClass("hidden"); 
    });
    $('li a#portfolio-toggle').click(function(){
        $('li#portfolio').animate({"height": "toggle", "opacity": "toggle"}, "slow").toggleClass("hidden"); 
    });
    $('li a#resume-toggle').click(function(){
        $('li#resume').animate({"height": "toggle", "opacity": "toggle"}, "slow").toggleClass("hidden"); 
    });
    $('li a#contact-toggle').click(function(){
        $('li#contactme').animate({"height": "toggle", "opacity": "toggle"}, "slow").toggleClass("hidden"); 
    });
});

This currently allows the visitor of the website to open all of the elements, which is not only visually displeasing, but creates a few bugs, but mostly visually displeasing.

My question is, with the code I have remaining as in-tact as possible, how would I make it so they can only have ONE open at a time?

Thanks in advance, Jacob

EDIT:

    $(document).ready(function(){
    $('#about-toggle').click(function(){
        $("li.active").addClass("hidden");
        $('#about').animate({"height": "toggle", "opacity": "toggle"}, "slow").removeClass("hidden").addClass("active");
    });
    $('#portfolio-toggle').click(function(){
        $("li.active").addClass("hidden");
        $('#portfolio').animate({"height": "toggle", "opacity": "toggle"}, "slow").removeClass("hidden").addClass("active");
    });
    $('#resume-toggle').click(function(){
         $("li.active").addClass("hidden");
        $('#resume').animate({"height": "toggle", "opacity": "toggle"}, "slow").removeClass("hidden").addClass("active");
    });
    $('#contact-toggle').click(function(){
        $("li.active").addClass("hidden");
        $('li#contactme').animate({"height": "toggle", "opacity": "toggle"}, "slow").removeClass("hidden").addClass("active");
    });
});

Solution

  • Put a common class on all the elements you want to close. Close them all except the one you clicked on and then open the one you clicked on. The ones that are already closed will do nothing when you close them again.

    Suppose you added the class togglers to each one, then you could do this and also shorten your jQuery into one block for all elements:

    $(document).ready(function(){
        $('#about-toggle, #portfolio-toggle, #resume-toggle, #contact-toggle').click(function(){
            // get the clicked on id and convert it to shortened form
            var id = this.id.replace(/\-.*$/, "");
            var item = $("#" + id);
            // toggle others that are open and toggle the current one
            $(".togglers").not(".hidden").add(item).animate({"height": "toggle", "opacity": "toggle"}, "slow").toggleClass("hidden"); 
        });
    });
    

    or, if you don't put the common class on them, then you just have to list them all:

    $(document).ready(function(){
        $('#about-toggle, #portfolio-toggle, #resume-toggle, #contact-toggle').click(function(){
            // get the clicked on id and convert it to shortened form
            var id = this.id.replace(/\-.*$/, "");
            var item = $("#" + id);
            // toggle others that are open and toggle the current one
            $('#about, #portfolio, #resume, #contact').not(".hidden").add(item).animate({"height": "toggle", "opacity": "toggle"}, "slow").toggleClass("hidden"); 
        });
    });
    

    This implementation assumes that the .hidden class is applied to any items that are toggled closed and removed from any items that are open and the initial HTML state must match that.