No that is not fine. Youtube has ensured that their iframe_api code can load in parallel, resulting in virtually no difference to the loading speed of the page.
Attempting to do that after the button has been clicked is pig-headed and stubborn behavior and results in a worse experience for everyone. You are being foolish there.
1 Like
asasass
August 10, 2021, 10:07am
22
Would this be right.
function coverClickHandler(evt) {
const cover = evt.currentTarget;
showScript(cover);
const curtain = openCurtain(cover);
showVideo(curtain);
}
or this way?
function coverClickHandler(evt) {
const cover = evt.currentTarget;
const curtain = openCurtain(cover);
showScript(cover);
showVideo(curtain);
}
https://jsfiddle.net/d9ytaLn3/
function showScript(cover) {
const tag = document.createElement("script");
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
function openCurtain(cover) {
hide(cover);
const curtain = document.querySelector(".curtain");
curtain.classList.add("slide");
return curtain;
}
function showVideo(curtain) {
const thewrap = curtain.parentElement.querySelector(".wrap");
show(thewrap);
}
function coverClickHandler(evt) {
const cover = evt.currentTarget;
showScript(cover);
const curtain = openCurtain(cover);
showVideo(curtain);
}
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
}());
What you have called showScript is instead actually the code to load the script.
While that happens (it takes a lot of time to load the script) execution of your code carries on, and you attempt to show the video. That is guaranteed to fail because there is no video, there is no iframe area for the video. There isn’t even the script yet to create the iframe area for the video.
What there is, is a script that’s taking its time to load. Execution of the JavaScript code doesn’t stop while that script is loading.
When that iframe_api script has finally loaded, it looks for and runs a separate function. You cannot so what you are currently doing in your handler functions. You have guaranteed failure by doing that.
1 Like
asasass
August 10, 2021, 10:15am
24
I reorganized it here:
https://jsfiddle.net/3vasmj5y/
It goes from the openCurtain to the showScript to the showVideo.
function openCurtain(cover) {
hide(cover);
const curtain = document.querySelector(".curtain");
curtain.classList.add("slide");
return curtain;
}
function showScript(cover) {
const tag = document.createElement("script");
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
function showVideo(curtain) {
const thewrap = curtain.parentElement.querySelector(".wrap");
show(thewrap);
}
function coverClickHandler(evt) {
const cover = evt.currentTarget;
const curtain = openCurtain(cover);
showScript(cover);
showVideo(curtain);
}
Once again the showScript function loads the iframe_api code which takes a long time. JS doesn’t wait for that to load. Instead it just carries on trying to run showVideo and fails, because iframe_api hasn’t yet done its thing. You have guaranteed failure there once again.
asasass
August 10, 2021, 10:21am
26
This way is better?
https://jsfiddle.net/wyp1e4qf/
(function manageCurtain() {
"use strict";
function show(el) {
el.classList.remove("hide");
}
function hide(el) {
el.classList.add("hide");
}
function openCurtain(cover) {
hide(cover);
const curtain = document.querySelector(".curtain");
curtain.classList.add("slide");
return curtain;
}
function showVideo(curtain) {
const thewrap = curtain.parentElement.querySelector(".wrap");
show(thewrap);
}
function coverClickHandler(evt) {
const cover = evt.currentTarget;
const curtain = openCurtain(cover);
showVideo(curtain);
}
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
}());
const videoPlayer = (function makeVideoPlayer() {
"use strict";
let player = null;
function loadIframeScript() {
const tag = document.createElement("script");
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
function onPlayerReady(event) {
player = event.target;
player.setVolume(100); // percent
}
let hasShuffled = false;
function onPlayerStateChange(event) {
player = event.target;
const shufflePlaylist = true;
if (!hasShuffled) {
player.setShuffle(shufflePlaylist);
player.playVideoAt(0);
hasShuffled = true;
}
}
function addPlayer(video) {
const playlist = "M7lc1UVf-VE";
const config = {
height: 360,
host: "https://www.youtube-nocookie.com",
width: 640
};
config.playerVars = {
autoplay: 0,
cc_load_policy: 0,
controls: 1,
disablekb: 1,
fs: 0,
iv_load_policy: 3,
loop: 1,
playlist,
rel: 0
};
config.events = {
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
};
player = new YT.Player(video, config);
}
function init() {
loadIframeScript();
}
return {
addPlayer,
init
};
}());
function onYouTubeIframeAPIReady() {
const cover = document.querySelector(".play");
const wrapper = cover.parentElement;
const frameContainer = wrapper.querySelector(".video");
videoPlayer.addPlayer(frameContainer);
}
(function iife() {
"use strict";
function coverClickHandler(evt) {
videoPlayer.init();
}
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
}());
That way works at least, but there’s a really slow delay after clicking the button until the video loads.
This modification so that the iframe API loads before you click the button, results in a much faster video playing experience.
asasass
August 10, 2021, 10:39am
28
or, I can remove playVideo
And use:
autoplay: 1, instead
https://jsfiddle.net/L1vxowh6/
}
function init() {
loadIframeScript();
}
return {
addPlayer,
init
};
}());
function onYouTubeIframeAPIReady() {
const cover = document.querySelector(".play");
const wrapper = cover.parentElement;
const frameContainer = wrapper.querySelector(".video");
videoPlayer.addPlayer(frameContainer);
}
(function iife() {
"use strict";
function coverClickHandler(evt) {
videoPlayer.init();
}
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
}());
No, using autoplay doesn’t work there either as there’s a really slow delay after clicking the button. That’s when the iframe API is loading.
The iframe API must load before the button click. If it happens after the click then you are always going to have that really slow delay.
asasass
August 10, 2021, 10:46am
30
Then it should stay as how it was originally.
https://jsfiddle.net/182tL0f5/
function play() {
player.playVideo();
}
return {
addPlayer,
play
};
}());
function onYouTubeIframeAPIReady() {
const cover = document.querySelector(".play");
const wrapper = cover.parentElement;
const frameContainer = wrapper.querySelector(".video");
videoPlayer.addPlayer(frameContainer);
}
(function iife() {
"use strict";
function coverClickHandler(evt) {
videoPlayer.play();
}
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
}());
Hey - that one works really well. There’s no delay at all when clicking the button now.
1 Like
system
Closed
November 15, 2021, 2:23pm
33
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.