我在这里所做的只是试图消除延迟。
直到在第 140 行调用 createPlayer(args)
之后,YouTube 视频(又名 iframe)才会被创建。因为它是点击处理程序的一部分,这意味着它是在点击之后创建的.提取和加载视频时出现延迟。
如何在代码中解决这个问题,以免出现延迟?
重现:点击运行,然后播放图像,重复执行以查看延迟。
点击播放图片后,并没有直接进入视频,出现了明显的延迟。
我该如何消除这种延迟?
点击运行,不更新测试Jsitor代码:https://jsitor.com/W0Iu1msGS
您可以编辑 JS Fiddle 链接:https://jsfiddle.net/w2Lphczf/
延迟出现在两者中。
const manageCover = (function makeManageCover() {
const config = {};
function show(el) {
el.classList.remove("hide");
}
function hide(el) {
el.classList.add("hide");
}
function hideAll(elements) {
elements.forEach(hide);
}
function showCovers(playButton) {
const cover = playButton.parentElement;
cover.classList.add("active");
show(cover);
}
function coverClickHandler(evt) {
hideAll(config.containers);
const cover = evt.currentTarget;
showCovers(cover);
}
function addClickToButtons(playButtons) {
playButtons.forEach(function addEventHandler(playButton) {
playButton.addEventListener("click", coverClickHandler);
});
}
function addCoverHandler(coverSelector, handler) {
const cover = document.querySelector(coverSelector);
cover.addEventListener("click", handler);
}
function init(selectors) {
config.containers = document.querySelectorAll(selectors.container);
const playButtons = document.querySelectorAll(selectors.playButton);
addClickToButtons(playButtons);
}
return {
addCoverHandler,
init,
show
};
}());
const manageCover = (function makeManageCover() {
const config = {};
function show(el) {
el.classList.remove("hide");
}
function hide(el) {
el.classList.add("hide");
}
function hideAll(elements) {
elements.forEach(hide);
}
function showCovers(playButton) {
const cover = playButton.parentElement;
cover.classList.add("active");
show(cover);
}
function coverClickHandler(evt) {
hideAll(config.containers);
const cover = evt.currentTarget;
showCovers(cover);
}
function addClickToButtons(playButtons) {
playButtons.forEach(function addEventHandler(playButton) {
playButton.addEventListener("click", coverClickHandler);
});
}
function addCoverHandler(coverSelector, handler) {
const cover = document.querySelector(coverSelector);
cover.addEventListener("click", handler);
}
function init(selectors) {
config.containers = document.querySelectorAll(selectors.container);
const playButtons = document.querySelectorAll(selectors.playButton);
addClickToButtons(playButtons);
}
return {
addCoverHandler,
init,
show
};
}());
const videoPlayer = (function makeVideoPlayer() {
const players = [];
let player = null;
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 onPlayerReady(event) {
player = event.target;
player.setVolume(100);
player.playVideo();
}
function addPlayer(video, settings) {
const defaults = {
playerOptions: {
events: {
"onReady": onPlayerReady
},
host: "https://www.youtube-nocookie.com",
videoId: video.dataset.id
}
};
const playerOptions = Object.assign(defaults.playerOptions, settings);
players.push(new YT.Player(video, playerOptions));
}
return {
addPlayer
};
}());
const managePlayer = (function makeManagePlayer() {
const defaults = {
playerOptions: {
height: 600,
playerVars: {
controls: 1,
disablekb: 1,
enablejsapi: 1,
fs: 0,
iv_load_policy: 3,
rel: 0
},
width: 360
}
};
function show(el) {
el.classList.remove("hide");
}
function createPlayerOptions(settings) {
function paramInOptions(opts, param) {
if (settings[param] !== undefined) {
opts[param] = settings[param];
delete settings[param];
}
return opts;
}
const optionParams = ["width", "height", "videoid", "host"];
const defaultOptions = defaults.playerOptions;
const preferred = optionParams.reduce(paramInOptions, {});
const playerOptions = Object.assign({}, defaultOptions, preferred);
// settings should now only consist of playerVars
const defaultPlayerVars = defaultOptions.playerVars;
const playerVars = Object.assign({}, defaultPlayerVars, settings);
playerOptions.playerVars = playerVars;
return playerOptions;
}
function createPlayer(videoWrapper, settings = {}) {
const video = videoWrapper.querySelector(".video");
const playerOptions = createPlayerOptions(settings);
return videoPlayer.addPlayer(video, playerOptions);
}
function createCoverClickHandler(playerSettings) {
return function coverClickHandler(evt) {
const cover = evt.currentTarget;
const wrapper = cover.nextElementSibling;
show(wrapper);
const player = createPlayer(wrapper, playerSettings);
wrapper.player = player;
};
}
function addPlayer(coverSelector, playerSettings) {
const clickHandler = createCoverClickHandler(playerSettings);
manageCover.addCoverHandler(coverSelector, clickHandler);
}
function init(playerOptions) {
Object.assign(defaults.playerOptions, playerOptions);
}
return {
add: addPlayer,
init
};
}());
function onYouTubeIframeAPIReady() {
managePlayer.add("svg.playa", {
height: 207,
width: 277
});
managePlayer.add("svg.playb", {
height: 207,
width: 277
});
manageCover.init({
container: ".container",
playButton: ".thePlay"
});
}
最佳答案
您可以在点击事件发生之前创建播放器。一种可能的方法是在 createCoverClickHandler
中执行此操作。
function createCoverClickHandler(playerSettings) {
// Grap the relevant HTML nodes and create the players early
Array.from(document.querySelectorAll('.curtain')).forEach(curtain => {
const player = createPlayer(curtain, playerSettings)
curtain.player = player
})
return function coverClickHandler(evt) {
const cover = evt.currentTarget;
const wrapper = cover.nextElementSibling;
show(wrapper);
};
}
您可能希望根据此更改调整其他内容,但这应该会在触发点击事件之前完成对 new YT.Player
的调用。
关于javascript - 试图消除延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69007380/