Reputation:
I have a slight issue with a loop I've built. It's the first time I've tried to construct a loop using jQuery. It's a simple read more/less button.
The issue I'm having is a strange one. When the page first loads it works perfectly, but any time after that, it runs the whole thing without considering the change to the ID.
HTML:
<div class="inner_container" id="tag_info"><?php?></div>
<a id="read_more">read more ></a>
jQuery:
$('a#read_more').click(function() {
$('#tag_info').stop().animate({
height: '100%'
}, 500 );
$(this).text('< read less');
$(this).removeAttr('id');
$(this).attr('id', 'read_less');
$('a#read_less').click(function() {
$('#tag_info').stop().animate({
height: '50px'
}, 500 );
$(this).text('read more >');
$(this).removeAttr('id');
$(this).attr('id', 'read_more');
});
});
CSS: [anchor styles not necessary]
#tag_info {
height: 50px;
overflow: hidden;
}
What happens (any time after the first time) is the div will animate to the height set in the first click function instantly, and then jump back to the height set in the second click function.
If I separate them into two different click functions, the second one doesn't work. The most confusing thing is that it works once, then fails to work properly. Any suggestions?
Upvotes: 5
Views: 167
Reputation: 318212
A simple toggling functionality should do :
$('#read_more').on('click', function() {
var state = $(this).text() == 'read more >';
$('#tag_info').stop().animate({
height: (state ? '100%' : '50px')}, 500 );
$(this).text(state ?'< read less' : 'read more >');
});
As a sidenote, animating values both in percentages and pixels can sometimes cause issues.
Upvotes: 2
Reputation: 2560
You are adding another handler in the click handler to the same element, which is causing the trouble.
$('a#read_less').click(function () {
$('#tag_info').stop().animate({
height: '50px'
}, 500);
$(this).text('read more >');
$(this).removeAttr('id');
$(this).attr('id', 'read_more');
});
Try this (http://jsfiddle.net/balintbako/nc5Dp/):
$('#read_more').click(function () {
if ($(this).hasClass("more")) {
$('#tag_info').stop().animate({
height: '100%'
}, 500);
$(this).text('< read less');
} else {
$('#tag_info').stop().animate({
height: '50px'
}, 500);
$(this).text('read more >');
}
$(this).toggleClass("more");
});
Upvotes: 0
Reputation: 887
Change your script as follows:
$('a#read_more').live("click",function() {
$('#tag_info').stop().animate({
height: '100%'
}, 500 );
$(this).text('< read less');
$(this).removeAttr('id');
$(this).attr('id', 'read_less');
$('a#read_less').live("click",function() {
$('#tag_info').stop().animate({
height: '50px'
}, 500 );
$(this).text('read more >');
$(this).removeAttr('id');
$(this).attr('id', 'read_more');
});
});
Upvotes: 1
Reputation: 33661
Use event delegation if you want to dynamically change the ID's..
$('body').on('click','#read_more',function() {
$('#tag_info').stop().animate({
height: '100%'
}, 500 );
$(this).text('< read less').attr('id', 'read_less');
});
$('body').on('click','#read_less',function() {
$('#tag_info').stop().animate({
height: '50px'
}, 500 );
$(this).text('read more >').attr('id', 'read_more');
});
By delegating you bind to a static parent element that exists in the DOM when the binding occurs. It will handle the events as they bubble up from your dynamic ID's. Direct and Delegated Events
Upvotes: 2
Reputation: 27012
I believe when you bind an event to an element, the event is bound to that specific element, regardless of whether you change the id later.
Rewrite this as a toggle or use jQuery's on
with event delegation instead: http://api.jquery.com/on/
Upvotes: 2