Splice jQuery array of elements

hybrid9 picture hybrid9 · Jan 7, 2014 · Viewed 19.9k times · Source

I'm trying to remove elements from a jQuery object using splice().
But, what ends up happening is every other item is removed. I'm assuming this is due to a re-index of using splice.
I was to fade in each <li> so I need to start at the top.
Is there a way to accomplish this, or perhaps a better way than what I'm doing here?

<ul>
    <li class="module">item 1</li>
    <li class="module">item 1</li>
    <li class="module">item 1</li>
    <li class="module">item 1</li>
    <li class="module">item 1</li>
    <li class="module">item 1</li>
    <li class="module">item 1</li>
</ul>

<script>
    var $modules = $('.module');

    $modules.each(function(i, el) {
        var $el = $modules.eq(i);

        $modules.splice(i, 1);

        $el.addClass("fadein").removeClass('module');
    });

    console.log($modules);
</script>

You'll notice in the console, every other item is still in the array.

jsFiddle: http://jsfiddle.net/tvWUc/5/

Answer

Oleg picture Oleg · Jan 7, 2014

This code should work:

var $modules = $('.module');
$modules.each(function(i) {
    var $el = $modules.eq(0);

    $modules.splice(0, 1);
    $el.addClass("fadein").removeClass('module');
});

EXPLAINATION

When you use each method, jQuery call your callback for each element, passing i as an index of current element.

So let's say you have an array: [elem1, elem2, elem3, elem4].

On the first step i equals 0. So by writing $el = $modules.eq(i); you get the first element, as expected. then you remove it form array, and now it looks like that: [elem2, elem3, elem4]. On the second step i equals 1, which means second element of your array, that is elem3 actually.

As you can see you jumped over elem2. Thats why some elements remain in an array.

To avoid this behavior you have to use zero index: var $el = $modules.eq(0); and $modules.splice(0, 1);

This is a demo