1

I’m trying have more than one YouTube embed video on the page, each of which has it’s own overlay and play button that when clicked hides the relevant overlay and plays video.

I can make it work for a single video, but when I try and add more in and loop over the videos, the onPlayerReady function doesn't seem to be getting called.

https://codepen.io/anon/pen/mqeZgX

Here's my javascript

// Inject YouTube API script
const tag = document.createElement('script');
tag.src = '//www.youtube.com/player_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

const players = document.querySelectorAll('.js-video-embed > iframe');
const playButtons = document.querySelectorAll('.video__button');
const overlays = document.querySelectorAll('.video__overlay');

window.onYouTubePlayerAPIReady = () => {
  for (var i = 0; i < players.length; i++) {
    new YT.Player(players[i], {
      events: {
        'onReady': onPlayerReady
      },
    });
  }
};

function onPlayerReady() {
  for (var i = 0; i < players.length; i++) {
    // bind events
    playButtons[i].addEventListener('click', () => {
      players[i].playVideo();
      overlays[i].style.display = 'none';
    });
  }
}

Thanks in advance for any pointers you may be able to give!

  • Based from this [thread](https://css-tricks.com/play-button-youtube-and-vimeo-api/), make sure that the iframe src URL has `?enablejsapi=1` at the end. It was also stated in this [link](https://stackoverflow.com/a/35699730/5832311) that the reason onPlayerReady didn't work was that iframe was missing an attribute: `enablejsapi="1"` and also missing `?enablejsapi=1` in YouTube video url.You may also refer with this SO post: https://stackoverflow.com/questions/42073012/play-and-pause-buttons-for-multiple-youtube-videos-on-the-same-page – abielita Nov 03 '17 at 15:33

1 Answers1

0

I had the same issue today and your code complemented what I had, so thank you for that if you still read this old question. I'll post it for whoever comes across this.

2 things to fix the code,

The first is that YT.Player expects an ID so you can't select all classes in the document and plug it in. Therefore, I selected all ID's in the document that start with video. The document has #video1 and #video2. Then you can get the ID and place it in YT.Player as parameter.

Second, when binding the EventListener the function .playVideo() is called on variable players but that is just the iframe. It needs to be called on YT.Player that gets created earlier. That's why I also updated the variable name players to videos. The new YT.Player gets stored in array players and is then used to call the function .playVideo()

Updated code:

const videos = document.querySelectorAll('iframe[id^="video"]')
let player;
let players = []
const playButtons = document.querySelectorAll('.video__button');

window.onYouTubePlayerAPIReady = () => {
    for (let i = 0; i < videos.length; i++) {
        player = new YT.Player(videos[i].id, {
            events: {
                'onReady': onPlayerReady
            },
        });
        players.push(player)
    }
};

function onPlayerReady() {
    for (let i = 0; i < videos.length; i++) {
        // bind events
        playButtons[i].addEventListener('click', () => {
            players[i].playVideo();
        });
    }
}
VAOpti
  • 1