Reputation: 5017
I have an expand/collapse block for which I have written a function as such:
function expandCollapse() {
var $btnShowHide = $('.btn-show-hide');
var $contentShowHide = $('.content-show-hide');
contentToggle();
$btnShowHide.each(function() {
$(this).on('click', function() {
var i = $btnShowHide.index(this);
$contentShowHide.eq(i).slideToggle('fast');
$contentShowHide.eq(i).toggleClass('collapsed');
if ($contentShowHide.eq(i).hasClass('collapsed')) {
$('.icon-show-hide', this).text('+');
} else {
$('.icon-show-hide', this).text('-');
}
});
});
function contentToggle() {
$contentShowHide.each(function() {
var i = $contentShowHide.index(this);
if ($(this).hasClass('collapsed')) {
$(this).hide();
$('.icon-show-hide', $btnShowHide.eq(i)).text('+');
} else {
$('.icon-show-hide', $btnShowHide.eq(i)).text('-');
}
});
}
}
and I call this function on $(document).ready
. This works fine but fails when there is an ajax call done in the page. So, I looked at this answer and called the function again on ajax success, but this makes the behaviour odd (like, clicking on the btn once will collapse and expand the content multiple times for a single click). Any ideas on how I can get around this?
Sample HTML (there could be multiple of these on one page):
<h3 class="btn-show-hide">
<span class="icon-show-hide"></span>
<span>Title</span>
</h3>
<div class="content-show-hide collapsed">
//Stuff
</div>
Upvotes: 0
Views: 312
Reputation: 5017
Apparently the solution is to set an off
before listening to the event.
So, it would just be
$btnShowHide.each(function() {
$(this).off('click').on('click', function() {
var i = $btnShowHide.index(this);
$contentShowHide.eq(i).slideToggle('fast');
$contentShowHide.eq(i).toggleClass('collapsed');
if ($contentShowHide.eq(i).hasClass('collapsed')) {
$('.icon-show-hide', this).text('+');
} else {
$('.icon-show-hide', this).text('-');
}
});
});
This fixed my problem but I have no idea why this works.
Upvotes: 1
Reputation: 3763
Unless you are removing/replacing all instances of $('.btn-show-hide');
and $('.content-show-hide');
before each call to expandCollapse()
you are re-adding the same event handler over and over, which I suspect is the cause of the multiple collapse/expands.
$btnShowHide.each(function() {
$(this).on('click', function() {
var i = $btnShowHide.index(this);
$contentShowHide.eq(i).slideToggle('fast');
$contentShowHide.eq(i).toggleClass('collapsed');
if ($contentShowHide.eq(i).hasClass('collapsed')) {
$('.icon-show-hide', this).text('+');
} else {
$('.icon-show-hide', this).text('-');
}
});
});
The above code adds a new event handler each time you call expandCollapse()
, perhaps it should be placed outside this function and only executed once...
Upvotes: 0