user2265712
user2265712

Reputation:

jQuery loop works once

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

Answers (5)

adeneo
adeneo

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.

FIDDLE

Upvotes: 2

Balint Bako
Balint Bako

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

karthi
karthi

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

wirey00
wirey00

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

Jason P
Jason P

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

Related Questions