简体   繁体   中英

jquery toggle won't close on click

I have this code for an accordion style toggle. Works great, only problem is, if you click on an open accordion, it slides up then back down. It doesn't slide closed.

Any thoughts?

Thanks!

//toggles 2
$('body').on('click','.toggle h3 a', function(){

    if($(this).parents('.toggles').hasClass('accordion')) return false;

    $(this).parents('.toggles').find('.toggle > div').slideUp(300);
    $(this).parents('.toggles').find('.toggle h3 a i').attr('class','icon-plus-sign');
    $(this).parents('.toggles').find('.toggle').removeClass('open');

    $(this).parents('.toggle').find('> div').slideDown(300);
    $(this).parents('.toggle').addClass('open');

    //switch icon
    if( $(this).parents('.toggle').hasClass('open') ){
        $(this).find('i').attr('class','icon-minus-sign');
    } else {
        $(this).find('i').attr('class','icon-plus-sign');
    }

    return false;
});



<div class="toggles">

<div class="toggle accent-color"><h3><a href="#"><i class="icon-minus-sign"></i>First Accord</a></h3>
    <div>
    Content
    </div>
</div> 

<div class="toggle accent-color"><h3><a href="#"><i class="icon-minus-sign"></i>Second Accord</a></h3>
    <div>
    Content
    </div>
</div> 

It's pretty simple why it does that. Your function always execute slideUp and slideDown. In that order. So when your div is collapsed, it will execute slideUp(which doesn't really make anything because it's already collapsed) and then it will slideDown. Now, when the div is expanded: The div will slideUp (this time it does go Up because it's not collapsed) and then it will go Down.

A better way to do it would be with SlideToggle.

http://api.jquery.com/slidetoggle/

EDIT: Also, you can check if the div is collapsed or not with...

if($(element).is(':visible')){
   //expanded
} else {
   //collapsed
}

Sorry I didn't really understand what was happening with your code so I rewrote the js part from scratch: http://jsfiddle.net/d503n47r/2/

$('body').on('click','.toggle h3 a', function(e){
    e.preventDefault();
    if($(this).parents('.toggles').hasClass('accordion')) return false;

    if ($(this).parents('.toggle').find('div').eq(0).hasClass('open')) {
            $(this).parents('.toggle').find('div').eq(0).removeClass('open').slideUp();
    } else {
            $('.toggle.open').removeClass('open');
            $(this).parents('.toggle').find('div').eq(0).addClass('open').slideDown();
    }

});

Please take a look at jquery UI as it helps a lot with all this common things http://jqueryui.com/ (No need to reinvent the wheel)

MinusFour was correct that it was firing both at the same time.

A way to remedy this is to do an if / then statement that checks whether or not it's open, and then fire's the open / close dependent on that.

Here's a link to a JSfiddle

I also added the class "toggle-panel" to the container that was sliding up / down, just so that following would be easier to read.

 if($(this).closest('.toggle').hasClass('open')){
        console.log('open');
        $(this).parents('.toggle').find('.toggle-panel').slideUp(300);
        $(this).closest('.toggle').removeClass('open');
        return
    }
    else {
        console.log('close');
        $(this).parents('.toggles').find('.toggle h3 a i').attr('class','icon-plus-sign');
        $(this).parents('.toggle').find('.toggle-panel').slideDown(300);
        $(this).parents('.toggle').addClass('open');
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM