user16940297
user16940297

Reputation:

How to add video.removeEventListener to code

Everytime I call the createResetHandler I bind the video.addEventListener to the same element.

I need to video.removeEventListener everytime I destroy the player.

How do I add video.removeEventListener to the code? https://jsfiddle.net/yb0tn7p9/

const videoPlayer = (function makeVideoPlayer() {
  const players = [];

  const tag = document.createElement("script");
  tag.src = "https://www.youtube.com/player_api";
  const firstScriptTag = document.getElementsByTagName("script")[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  function createResetHandler(player) {
    const resetVideos = document.querySelectorAll('.exit');
    resetVideos.forEach(function resetVideoHandler(video) {
        video.addEventListener('click', function resetVideoHandler() {
            player.destroy();
            console.log('hit')
          }
        );
      }
    )
  }

  function onPlayerReady(event) {
    const player = event.target;
    player.setVolume(100);
    createResetHandler(player);
  }

  function addPlayer(video, settings) {
    const defaults = {
      height: 360,
      host: "https://www.youtube-nocookie.com",
      videoId: video.dataset.id,
      width: 640
    };
    defaults.events = {
      "onReady": onPlayerReady
    };

    const playerOptions = combinePlayerOptions(defaults, settings);
    const player = new YT.Player(video, playerOptions);
    players.push(player);
    return player;
  }

  return {
    addPlayer
  };
}());

Upvotes: 4

Views: 541

Answers (2)

anees
anees

Reputation: 1855

you are adding event to each element whenever createResetHandler is called. What you should do instead is find the button that is related to that video and call add event listener to only that button.

 function createResetHandler(player) {
    // get the current exit button from the curtain element which's display is set to block
    let exitBtn = Array.from(document.querySelectorAll('.exit')).find(e => {
        return window.getComputedStyle(e.closest(".curtain")).display === 'block';
    });
    
    if(exitBtn){
        exitBtn.addEventListener('click', () => {
          console.log("hit");
          player.destroy();
        },{once: true}
       );
    }
  }

let me break it up a little. The thing we are sure of is there is only one exit button visible at the moment inside only one curtain whose display is block at the moment.

Array.from converts the NodeList into array so we can utilize the find method of array. From the button we get the closest (towards the parents) .curtain element and check the display prop using getComputedStyle to see if it is block.

If it is block that means this is the curtain that is being viewed and the button at this iteration is the button that needs to have click event listener.

and lastly the {once: true} part is to make sure the event is only listened one time. Since you are already using const keyword that means you are only going for modern browsers so no need to use removeEventListener seperately {once: true} will work in all the modern browsers.

updated working fiddle: https://jsfiddle.net/avwonj91/1/

Upvotes: 1

Titus
Titus

Reputation: 22474

You can modify the createResetHandler function to something like this:

function createResetHandler(player) {
    const resetVideos = document.querySelectorAll('.exit');
    resetVideos.forEach(function(video) {
        video.addEventListener('click', function resetVideoHandler() {
            video.removeEventListener('click', resetVideoHandler); 
            player.destroy();
            console.log('hit')
          }
        );
      }
    )
}

What I did is to only use the resetVideoHandler function name only once for the event handler function and to add the video.removeEventListener('click', resetVideoHandler) statement.

Upvotes: 1

Related Questions