Reputation: 2143
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
Reputation: 74420
Cancel click event if element is animated:
$(".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
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
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...
$(".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
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();
});
Upvotes: 4
Reputation: 5610
Use .stop()
$('p').stop().slideUp();
$(this).next().stop().slideDown();
Upvotes: 0