Pipo
Pipo

Reputation: 988

Getting previous element in for loop

EDIT 2 (to make the problem more understandable)

The effect I am trying to achieve is the following: everytime an element enters the viewport an 'is-visible' class is added to it and the same 'is-visible' class is removed from the previous element.

Now I've managed to make it work but I run a for loop to remove all is-visible classes before adding the is-visible class to the element in viewport.

It works but in terms of performance I think it would be better to just remove the class from element[i -1]. And this were I can't get it working.

Here is a simplified fiddle were I try to make the element[i-1] solution work: https://jsfiddle.net/epigeyre/vm36fpuo/11/.


EDIT 1 (to answer some of the questions asked)

I have corrected an issue raised by @Catalin Iancu (thanks a lot for your precious help) by using a modulus operator ((i+len-1)%len).


ORIGINAL QUESTION (not really clear)

I am trying to get the previous element in a for loop (to change its class) with following code :

for (var i = 0; i < array.length; i++) {
    if(array[i-1] && my other conditions) {
        array[i-1].classList.remove('is-visible');
        array[i].classList.add('is-visible');
    }
}

But it's not removing the class for [i-1] element.

Here is a more complete piece of code of my module (this is running within a scroll eventlistener):

var services = document.getElementsByClassName('services'),
    contRect = servicesContainer.getBoundingClientRect();

for (var i = 0; i < services.length; i++) {
    var serviceRect = services[i].getBoundingClientRect();

    if ( !services[i].classList.contains('active') && Math.round(serviceRect.left) < contRect.right && services[i-1]) {
        services[i-1].classList.remove('is-visible');
        services[i].classList.add('is-visible');
    }
}

Thanks for your help!

Upvotes: 0

Views: 597

Answers (3)

Catalin Iancu
Catalin Iancu

Reputation: 722

Your if(array[i-1] && my other conditions) is always true, except for the very first case where array[-1] doesn't exist. Therefore, it will remove and then add the active class for each element, which will make it seem as only the first element's class has been removed.

What you need is a better if condition or a break statement, when the loop is not needed anymore

for (var i = 0; i < array.length; i++) {
    if(array[i] && i != array.length - 1) {
        array[i].classList.remove('active');
    }
}
array[array.length - 1].classList.add('active');

Upvotes: 1

Sara
Sara

Reputation: 45

What if you create a variable that contain the previous element?

var previous = array[0];
for (var i = 0; i < array.length; i++) {
    if(previous && my other conditions) {
        previous.classList.remove('active');
        array[i].classList.add('active');
    break;
    }
    previous = array[i];
}

Upvotes: 0

S.Serpooshan
S.Serpooshan

Reputation: 8388

The problem probably is that based on your code: services[i-1].classList.remove('active'); and services[i].classList.add('active'); the 'active' class you add in current iteration will be removed in next iteration!

So your code has logical errors, array index does not return all prev items!

Upvotes: 0

Related Questions