user1251698
user1251698

Reputation: 2143

Stop item sliding multiple times in jQuery

I want to create a basic toggle list. Clicking an item title should slide down its content, and slide up the any other item content.

The following code works, but there is a problem that if I click on an item multiple times, it will slide up and down as many times it is clicked.

Is there a way to improve it so that even if you click on same item multiple times, slide it only once.

JQuery:

$(".title").click(function(e){
    e.preventDefault();
    $('.item').removeClass("active");
    $(this).parent().addClass("active");
    $('p').slideUp();
    $(this).next().slideDown();
});

HTML:

<div class="wrap">
    <div class="item">
        <div class="title">title1</div>
        <p>content</p>
    </div>
    <div class="item">
        <div class="title">title2</div>
        <p>content</p>
    </div>
</div>

See the demo here, if you click on title multiple times, you will see that:

JSFiddle: http://jsfiddle.net/a7H27/

Upvotes: 2

Views: 962

Answers (5)

A. Wolff
A. Wolff

Reputation: 74420

Cancel click event if element is animated:

DEMO

$(".title").click(function(e){
    if($('.item, p').is(':animated')) return;
    e.preventDefault();
    $('.item').removeClass("active");
    $(this).parent().addClass("active");
    $('p').slideUp();
    $(this).next().slideDown();
});

Upvotes: 2

Seth
Seth

Reputation: 10454

I do not recommend using .stop(), for it stops the animations immediately, leaving an unfinished animation if clicked a second time.

I recommend checking if the .item has an .active class and if it doesn't, animate it's paragraph, like so.

JSFiddle - Here

$(".title").click(function(e){
    e.preventDefault();
    //$('.item').removeClass("active");
    //$(this).parent().addClass("active");
    //$('p').slideUp();
    //$(this).next().slideDown();


    // Track which item we're referring to
    var item = $(this).parent('.item');
    // If item isn't active
    if(!item.hasClass('active')){
        // Remove all active classes on .item
        $('.item').removeClass('active');
        // Add class to clicked .item
        item.addClass('active');
        // Sliding all paragraphs like before might be bad in 
        // the future. Select .item paragraphs
        $('.item p').slideUp();
        // Find this item's paragraph and slide down.
        item.find('p').slideDown();
    };
});

Upvotes: 1

apaul
apaul

Reputation: 16170

I would probably use a simple if statement to test if the parent has the active class, which has the added bonus of optionally being able to collapse open panes if you need to...

Working Example

$(".title").click(function (e) {
    if (!$(this).parent().hasClass('active')) {
        e.preventDefault();
        $('.item').removeClass("active");
        $(this).parent().addClass("active");
        $('p').slideUp();
        $(this).next().slideDown();
    } else { //optionally closes open panes, remove if desired
        $('.item').removeClass("active");
        $('p').slideUp();
    }
});

Upvotes: 2

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67217

The .stop() will clear the animations which are in queue for the particular element. So that the unnecessary clicks would be ignored. Please read this to know more about .stop()

Try this,

$(".title").click(function(e){
    e.preventDefault();
    $('.item').removeClass("active");
    $(this).parent().addClass("active");
    $('p').slideUp();
    $(this).next().stop().slideDown();
});

DEMO

Upvotes: 4

Milan and Friends
Milan and Friends

Reputation: 5610

Use .stop()

$('p').stop().slideUp();
$(this).next().stop().slideDown();

Upvotes: 0

Related Questions