suicidebilly
suicidebilly

Reputation: 295

SlideToggle and Callback, am I doing something wrong or is this a bug?

I have a page with Four Item buttons, when the user click on these buttons the Content should slideDown.

If it is already a visible content this content must be slided up and then the right content should be slided Down.

Everything works fine, but if the user click fast between the Item Buttons the slides get jammed and start to appear on top of the others.

Here is an example.: http://jsfiddle.net/7t6Eh/42/

If the user click "slow" between the Items, everything works ok.

I've already tried to use '.is(": visible")' but got the same results.

Can anyone help me out?

CODE

var active = 0;

    $("#item1").click(function(){

        if (active == 0){

            $("#ContentList1").stop().slideToggle(function() {
                active = 1;
            });

        } else {

            if (active != 1){
                $("#ContentList" + active).stop().slideToggle(function() {

                    $("#ContentList1").stop().slideToggle(function() {
                        active = 1;
                    });

                });
            }
        }
    });

    $("#item2").click(function(){

        if (active == 0){

            $("#ContentList2").stop().slideToggle(function() {
                active = 2;
            });

        } else {

            if (active != 2){
                $("#ContentList" + active).stop().slideToggle(function() {

                    $("#ContentList2").stop().slideToggle(function() {
                        active = 2;
                    });

                });
            }
        }
    });

    $("#item3").click(function(){

        if (active == 0){

            $("#ContentList3").stop().slideToggle(function() {
                active = 3;
            });

        } else {

            if (active != 3){
                $("#ContentList" + active).stop().slideToggle(function() {

                    $("#ContentList3").stop().slideToggle(function() {
                        active = 3;
                    });

                });
            }
        }
    });    

    $("#item4").click(function(){

        if (active == 0){

            $("#ContentList4").stop().slideToggle(function() {
                active = 4;
            });

        } else {

            if (active != 4){
                $("#ContentList" + active).stop().slideToggle(function() {

                    $("#ContentList4").stop().slideToggle(function() {
                        active = 4;
                    });

                });
            }
        }
    });

Upvotes: 5

Views: 792

Answers (2)

Tallmaris
Tallmaris

Reputation: 7590

I usuallly do this kind of things taking advantage of siblings() to select adjacent divs and stop them, rather than using an "active" var to store the active div:

$(document).ready(function(){
    $("#item1").click(function(){
        $('#' + $(this).attr('for'))
            .slideDown().siblings('div').stop().slideUp()
    });
    $("#item2").click(function(){
        $('#' + $(this).attr('for'))
            .slideDown().siblings('div').stop().slideUp()
    });
    $("#item3").click(function(){
        $('#' + $(this).attr('for'))
            .slideDown().siblings('div').stop().slideUp()
    });
    $("#item4").click(function(){
        $('#' + $(this).attr('for'))
            .slideDown().siblings('div').stop().slideUp()
    });
});

you can use the "for" attribute (or any other) to specify the div that the link is referring. For example:

<div id="item1" for="ContentList1" style="float: left; width: 50px; cursor: pointer;">Item1</div>

​ An example working fiddle: http://jsfiddle.net/7t6Eh/46/

ADDED: If you want to do the close animation before the open animation, you can use jQuery deferred like this:

$("#item1").click(function(){
    content = $('#' + $(this).attr('for'));
    $.when(content.siblings('div').stop().slideUp())
        .then(function () { content.slideDown() });
});

of course apply to all 4 click events. Example: http://jsfiddle.net/7t6Eh/52/

Upvotes: 2

Selven
Selven

Reputation: 276

http://jsfiddle.net/7t6Eh/50/

This should do what you are trying to achieve. It gets the position of the list item clicked and shows the content you want based on that. Let me know f you need anything else explained

var active = -1;
$('.content').hide();
$('ul li').click(function() {
    var index = $(this).index('ul li');
    if( active == index) {
        // this item already active, do nothing
    } else {
        // show the content you want
        $('.content').stop().slideUp();
        $('.content').eq(index).slideDown()
    }
    active = index
})

Upvotes: 1

Related Questions