Question

I have a jQuery issue that I cant get my head around. Basically, I have a horizontal timeline that shows a number of events of a company. These events are set up with an accordion effect which is working fine. I am trying to add a close button to each accordion panel and am getting stuck in a loop at the moment.

If the panel is clicked on, the code checks to see whether or not there is a class attached called "active". If not, it adds it and expands the panel. I have added my close link and said to remove the "active" class, which works, but once it realises it no longer has the class, it re-adds it. So I am stuck in this loop which I cant get out of :)

Any help would be great!

A jsfiddle of the issue can be seen here: http://jsfiddle.net/damienoneill2001/DdALd/8/

As you click through the different panels, you can see they work. A Close button is set on the second panel and becomes visible once any panel is clicked. If you click on the close button but then click on the same panel again, you can see it gets caught in the loop.

Also, if you open a panel, click on the same panel again to close and then try open it again, it gets caught in the same loop.

jQuery code:

$(document).ready(function()
 {
    activePanel = $("#accordion .panel:first");
    $(activePanel).addClass('active');
    $(".panel").click(function(){

if($(this).not('.active') )
{
    $(this).animate({width: "400px"}, 300);
    $(this).addClass('active');
    $(activePanel).animate({width: "60px"}, 300);
    activePanel = this;
    $('.close').css({display: "block"});

    }

}); 
$(".close").click(function(){
     $('.close').css({display: "none"});
     $('.panel').removeClass('active');
    });

});
Was it helpful?

Solution

Use hasClass

if(!$(this).hasClass('.active') )
{
    $(this).animate({width: "400px"}, 300);
    $(this).addClass('active');
    $(activePanel).animate({width: "60px"}, 300);
    activePanel = this;
    $('.close').css({display: "block"});

}

Edit

I've updated your code provided in the fiddle

$(document).ready(function () {
    activePanel = $("#accordion div.panel:first");
    $(activePanel).addClass('active');
    $(".panel").click(function () {
        if ($(this).not('.active')) {
            $(".active").animate({
                width: "60px"
            }, 300);
            if ($(this).css("width") == "400px") {
                $(this).animate({
                    width: "60px"
                }, 300);
                $('.close').hide();
            } else {
                $(this).animate({
                    width: "400px"
                }, 300);
                $('.close').show();
            }
            $(this).addClass("active");
        }

    });
    $(".close").click(function (e) {
        e.stopPropagation();
        $(this).hide();
        $(".active").animate({
            width: "60px"
        }, 300);

    });

});

Demo

OTHER TIPS

change not to is

if(!$(this).is('.active') )
{
    $(this).animate({width: "400px"}, 300);
    $(this).addClass('active');
    $(activePanel).animate({width: "60px"}, 300);
    activePanel = this;
    $('.close').css({display: "block"});

    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top