Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove scroll event listener?

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}%)`;
        }
    });
like image 415
Roman Avatar asked Jan 18 '19 13:01

Roman


People also ask

How do I remove event listener?

JavaScript | removeEventListener() method with examples The removeEventListener() is an inbuilt function in JavaScript which removes an event handler from an element for a attached event. for example, if a button is disabled after one click you can use removeEventListener() to remove a click event listener.

How do I remove an event listener from my website?

Event listeners can also be removed by passing an AbortSignal to an addEventListener() and then later calling abort() on the controller owning the signal.

How do I get rid of event listener after one click?

Using the removeEventListener() method The JavaScript built-in function removeEventListener() removes an event handler from an element for a connected event. For instance, you can use removeEventListener() to get rid of a click event listener if a button is disabled after one click.


2 Answers

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);
like image 53
slightlynerd Avatar answered Oct 19 '22 03:10

slightlynerd


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.

like image 21
cloned Avatar answered Oct 19 '22 05:10

cloned