Why does jQuery .after() fire only once?

916 Views Asked by At

I'm trying to create a jQuery carousel that loops continuously. When the user selects "rotate," the first li is placed after the last li using the .after() method. This works the first time only. After that, the li's won't rearrange themselves. Here is my HTML:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

<a href="#">Rotate</a>

And here is my JavaScript:

var list = $('ul'),
    firstItem = list.find('li:first'),
    lastItem = list.find('li:last');

$('a').on('click', function(){
    lastItem.after( firstItem );
});

Here's a fiddle: http://jsfiddle.net/brianeoneill/76BP8/

Thanks in advance!

5

There are 5 best solutions below

1
SLaks On BEST ANSWER

Each time your code runs, it puts the same element (1) after the 3.

If you want to keep re-arranging, you'll need to re-set the variables to :first and :last each time.

1
Denys Séguret On

Inserting an element moves it if it's yet inserted.

Here, you're repeating the same insert at the same place, it doesn't do anything new.

1
j08691 On

Place your selectors within the click function:

var list = $('ul');
$('a').on('click', function(){
    var firstItem = list.find('li:first'),
    lastItem = list.find('li:last');
    lastItem.after( firstItem );
});

jsFiddle example

By keeping them outside of the click event, you're not changing the elements you select each time. By moving them inside you are.

0
freshbm On
var list = $('ul');

$('a').on('click', function(){
    firstItem = list.find('li:first'),
    lastItem = list.find('li:last');

    lastItem.after( firstItem );
});

http://jsfiddle.net/76BP8/2/

0
Kevin B On

You aren't updating the variables, therefore first item and last item will always be the same.

Here's an alternative if you want to keep the selections outside:

var list = $('ul'),
    firstItem = function(){
        return list.find('li:first');
    },
    lastItem = function(){
        return list.find('li:last');
    };

$('a').on('click', function(){
    lastItem().after( firstItem() );   
});

http://jsfiddle.net/76BP8/3/