How to remove scroll event listener?

17,777

Solution 1

You can only remove event listeners on external functions. You cannot remove event listeners on anonymous functions, like you have used.

Replace this code

window.addEventListener('scroll', () => { ... };

and do this instead

window.addEventListener('scroll', someFunction);

Then move your function logic into the function

function someFunction() {
  // add logic here
}

You can then remove the click listener when some condition is met i.e. when the element is in the viewport

window.removeEventListener('scroll', someFunction);

Solution 2

Instead of listening to scroll event you should try using Intersection Observer (IO) Listening to scroll event and calculating the position of elements on each scroll can be bad for performance. With IO you can use a callback function whenever two elements on the page are intersecting with each other or intersecting with the viewport.

To use IO you first have to specify the options for IO. Since you want to check if your element is in view, leave the root element out.

let options = {
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

Then you specify which elements you want to watch:

let target = slideMenu; //document.querySelector('#oneElement') or document.querySelectorAll('.multiple-elements')
observer.observe(target); // if you have multiple elements, loop through them to add observer

Lastly you have to define what should happen once the element is in the viewport:

let callback = (entries, observer) => { 
  entries.forEach(entry => {
    // Each entry describes an intersection change for one observed
    // target element:
  });
};

You can also unobserve an element if you don't need the observer anymore.

Check this polyfill from w3c to support older browsers.

Share:
17,777
Roman
Author by

Roman

Updated on July 22, 2022

Comments

  • Roman
    Roman almost 2 years

    I am trying to remove scroll event listener when I scroll to some element. What I am trying to do is call a click event when some elements are in a viewport. The problem is that the click event keeps calling all the time or after first call not at all. (Sorry - difficult to explain) and I would like to remove the scroll event to stop calling the click function.

    My code:

       window.addEventListener('scroll', () => {
       window.onscroll = slideMenu;
    
            // offsetTop - the distance of the current element relative to the top;
            if (window.scrollY > elementTarget.offsetTop) {
                const scrolledPx = (window.scrollY - elementTarget.offsetTop);
    
                // going forward one step
                if (scrolledPx < viewportHeight) {
                    // console.log('section one');
                    const link = document.getElementById('2');
                    if (link.stopclik === undefined) {
                        link.click();
                        link.stopclik = true;
                    }
                }
    
                // SECOND STEP
                if (viewportHeight < scrolledPx && (viewportHeight * 2) > scrolledPx) {
                    console.log('section two');
    
                    // Initial state
                    let scrollPos = 0;
                    window.addEventListener('scroll', () => {
                        if ((document.body.getBoundingClientRect()).top > scrollPos) { // UP
                            const link1 = document.getElementById('1');
                            link1.stopclik = undefined;
                            if (link1.stopclik === undefined) {
                                link1.click();
                                link1.stopclik = true;
                            }
                        } else {
                            console.log('down');
                        }
                        // saves the new position for iteration.
                        scrollPos = (document.body.getBoundingClientRect()).top;
                    });
                }
    
                if ((viewportHeight * 2) < scrolledPx && (viewportHeight * 3) > scrolledPx) {
                    console.log('section three');
                }
    
                const moveInPercent = scrolledPx / base;
                const move = -1 * (moveInPercent);
    
                innerWrapper.style.transform = `translate(${move}%)`;
            }
        });