1

I am trying to remove a class name once the user has scrolled a certain amount.

In my JS file for a LWC I have the following:

import { LightningElement, wire, api, track } from 'lwc';

function removeClass() {
    document.getElementsByClassName('outter-wrapper')[0].remove('outter-wrapper');
}

export default class SomeClass extends LightningElement {

    // some other code

    connectedCallback() {
        window.addEventListener('scroll', function() {
            if (window.pageYOffset > 260) {
                removeClass();
            }
        }
    }
}

I get an error in the console saying Cannot read property 'remove' of undefined.

When I do execute document.getElementsByClassName('outter-wrapper')[0].remove('outter-wrapper'); in the console it works no problem.

If this is the JS file for the LWC which contains a div with a class name outter-wrapper how come it cannot find it?

4

Firstly, document. is not allowed in LWC because of locker-service. You should be using this.template. to identify the elements in HTML.

Instead, you can add something like this:

import { LightningElement, wire, api, track } from 'lwc';

export default class SomeClass extends LightningElement {

    // some other code

    connectedCallback() {
        window.addEventListener('scroll', function() {
            if (window.pageYOffset > 260) {
                this.removeClass();
            }
        });
    }

    removeClass() {
        this.template.querySelectorAll('.outter-wrapper')[0].remove('outter-wrapper');
    }
}

Note (based on comments):

When you declare the function outside class, you are out of context of class and so this will be undefined and so you cannot access template. And document is exposed through secure object and so many methods on document will be unavailable. Still if you want to use functions outside class, you will need to pass the class reference via parameter like below:

import { LightningElement } from 'lwc';

function check(cls) {
    cls.template.querySelector('.myclass').remove('myclass');
}

export default class Poc extends LightningElement {
    remove() {
        check(this);
    }
}
  • Thank you. I see that you moved removeClass() inside my SomeClass class. I thought if the function is not to be referenced from the component then I should probably not put it inside the class. Is my trail of thought wrong? – Arthlete Aug 1 at 18:22
  • 1
    adding in answer – salesforce-sas Aug 1 at 18:24
1

You should not be using document to access the element. instead use this.template

See important note in the bottom of the documentation: Docs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.