Search code examples
javascripthtmlrefactoringmodularremoveeventlistener

How can I refactor this Javascript code to make it more modular and concise?


var vid1 = document.getElementById("v1");
var vid2 = document.getElementById("v2");
var vidArr = [vid1,vid2];

var tempListener1 = function checkViewA(){
    if(elementInView(vid1)){
        playVideo(vid1);
        window.removeEventListener('scroll', tempListener1); // so the video only plays once
    }
}

var tempListener2 = function checkViewB(){
    if(elementInView(vid2)){
        playVideo(vid2);
        window.removeEventListener('scroll', tempListener2);
    }
}

// scroll event listeners
window.addEventListener('scroll', tempListener1);
window.addEventListener('scroll', tempListener2); 

// this plays the video
async function playVideo(v){ 
    v.play();
}

I want to be able to keep adding videos that get played when they are in view without having to keep adding variables, event listeners. In javascript you can't remove-listeners that have functions with parameters which is why I put those into variables. Any insights would be welcome.


Solution

  • First get a collection of all videos elements in a Set, then add a single scroll listener. When the listener runs, iterate over the Set. Whenever a video is found which is in view, play it and remove it from the Set:

    const videos = new Set(document.querySelectorAll('video'));
    window.addEventListener('scroll', () => {
      for (const video of videos) {
        if (elementInView(video)) {
          video.play();
          videos.delete(video);
        }
      }
    });