Having the videos load first, means not initing them when the cover is clicked.
function coverClickHandler(evt) {
const wrapper = evt.currentTarget.nextElementSibling;
show(wrapper);
// initPlayer(wrapper);
}
and instead initing them when we init the cover event handler.
const cover = document.querySelector(opts.target);
cover.addEventListener("click", coverClickHandler);
const wrapper = cover.nextElementSibling;
initPlayer(wrapper);
We now have a few different ways to get the wrapper, so we should use a function to simplify that.
function getVideoWrapper(cover) {
return cover.nextElementSibling;
}
...
function coverClickHandler(evt) {
const cover = evt.currentTarget;
const wrapper = getVideoWrapper(cover);
show(wrapper);
}
...
const wrapper = cover.nextElementSibling;
initPlayer(wrapper);
Autoplay gets set to 0 so that they don’t automatically play:
opts = Object.assign(opts, {
autoplay: 0,
controls: 1,
We don’t need to use onPlayerReady anymore to play the video, because the video is already loaded. It’s just waiting for us to play it.
function coverClickHandler(evt) {
const cover = evt.currentTarget;
const wrapper = getVideoWrapper(cover);
show(wrapper);
videoPlayer.play(player);
}
But how do we get the player? We can attach a reference to it on the cover, as was similarly done in the other code.
We’ll start by having the addPlayer function return the player:
function addPlayer(video, settings) {
...
const player = new YT.Player(video, playerVars);
players.push(player);
return player;
}
We can have the initPlayer function take that player, and add it to the videoWrapper.
function initPlayer(videoWrapper) {
...
const player = videoPlayer.addPlayer(video, settings);
videoWrapper.player = player;
}
There is another problem though, it takes time for the players are are loading to load. We don’t want the cover click to occur before the players are ready.
We can have the onPlayerReady event handler initialise the covers. That way we won’t be able to click on the covers until the video is loaded.
function onPlayerReady() {
const coverSelector = opts.target;
manageCover.init(coverSelector);
const cover = document.querySelector(coverSelector);
cover.addEventListener("click", coverClickHandler);
}
const cover = document.querySelector(opts.target);
const videoWrapper = cover.nextElementSibling;
initPlayer(videoWrapper, onPlayerReady);
and because manageCover.init is being done when the video is ready, we can remove the manageCover.init sections from the end of the code too.
The initPlayer code just needs to know what to do with the onReady callback:
function initPlayer(videoWrapper, onReady) {
...
const player = videoPlayer.addPlayer(video, settings, onReady);
videoWrapper.player = player;
}
And similarly, the videoPlayer puts the onReady callback somewhere useful, so that it can be retrieved later.
function addPlayer(video, settings, onReady) {
...
const player = new YT.Player(video, playerVars);
player.onReady = onReady;
players.push(player);
return player;
}
That way, the onPlayerReady event handler can check for onReady and run that code.
function onPlayerReady(event) {
const player = event.target;
player.setVolume(100); // percent
shufflePlaylist(player);
if (player.onReady) {
player.onReady(player);
}
}
The videos now play without the play symbol, and without the loading animation.
There is one more thing to do though, and that is to give visual feedback for when the preloaded videos are ready to play, which I’ll do in the next post.