1

I am trying to remove a class from a certain element whenever the user clicks a button.

In the process I check whether the element has the class before removing it.

I am using a React component and I'm setting the class variable this.images in componentDidMount Also, the console.log in there confirms the array of images that i need.

    componentDidMount() {
        this.images = document.querySelectorAll(".project-image");
        console.log(this.images);
    }

    renderNextImage() {
        for (let i = 0, ilen = this.images.length; i < ilen; i++) {
            if (!this.images[i].classList.contains('d-none')) {
                this.images[i].classList.add('d-none');
                this.toggleNextImage(i);
            }
        }
    }
    toggleNextImage(count) {
        let max = this.images.length - 1;
        if (count < max) {
            count++;
            if (this.images[count].classList.contains('d-none')) {
                console.log("element contains class d-none");      // THIS WORKS
                this.images[count].classList.remove('d-none');
            }
        }
    }

The console log shows up in my console but the actual classList.remove part doesn't work.

What am I doing wrong?

Any help would be appreciated.

11
  • Can you post a minimal reproducible example, including the markup for the elements, how you are constructing the class and how you are calling the method? Commented Sep 27, 2018 at 21:43
  • I don't know if it helps but I just checked and the classList attribute have a toggle method Commented Sep 27, 2018 at 21:43
  • 3
    Btw, you don't need the if (….contains(…)) check, just call remove - it won't error when the class doesn't exist. Commented Sep 27, 2018 at 21:44
  • which browser are you using? Commented Sep 27, 2018 at 21:48
  • @WolganEns He's not actually toggling. One function always adds, the other one always removes. Commented Sep 27, 2018 at 21:48

2 Answers 2

1

The problem is that you're doing this in a loop. In renderNextImage() you call toggleNextImage(), which removes the class from the next element in the list. Then the loop repeats with the next value of i, which adds the class back.

You need to break out of the loop when you find the image to toggle.

renderNextImage() {
    for (let i = 0, ilen = this.images.length; i < ilen; i++) {
        if (!this.images[i].classList.contains('d-none')) {
            this.images[i].classList.add('d-none');
            this.toggleNextImage(i);
            break;
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

You're right, adding break; fixed it. Somebody in the comments said that this is not the best way of doing this. How would one do this more efficient?
You can save the index of the current image in a global variable, and just increment it. Or you can use querySelector(".d-none") and get the index of that element in its parent element.
0

This vanilla js remove works just if you apply it on the element, like in this example. You need to make sure if this code (this.images[count]) represents an element.

// JavaScript
var div = document.querySelector('div');
div.classList.remove('myClass');

9 Comments

This is really a comment, not an answer. With a bit more rep, you will be able to post comments. See why do I need 50 reputation to comment, what can I do instead for an explanation.
I agree with @Barmar don't ask a question in an answer
If it didn't represent the element, how could the contains() test work?
Yeah, I know man. But as you said. I can't create comments yet. So if I am trying to help with a comment I just post like I did.
The reason why i've added the contains() part, is because i wanted to make sure it did actually represent an element.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.