如何修改代码消除YouTube iframe播放器点击播放后的加载延迟
解决方案
核心思路是将播放器初始化逻辑从点击回调中提前到页面加载阶段完成,提前拉取视频资源,用户点击时直接触发播放即可消除延迟,具体修改如下:
调整要点
- 删除重复定义的第一份
manageCover冗余代码 - 修改播放器就绪后的默认逻辑,初始化后不自动播放,等待用户点击触发
- YouTube API加载完成后直接预创建所有播放器实例,隐藏对应容器
- 点击回调仅保留显示容器、触发播放、调整音量的逻辑
修改后完整代码
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 = []; 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) { const player = event.target; player.setVolume(0); player.pauseVideo(); } 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); const player = new YT.Player(video, playerOptions); players.push(player); return player; } 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, autoplay: 1 // 预加载需要开启自动播放,初始化后会立即暂停静音不影响用户感知 }, width: 360 } }; function show(el) { el.classList.remove("hide"); } function hide(el) { el.classList.add("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); 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 preCreatePlayer(coverSelector, playerSettings) { const cover = document.querySelector(coverSelector); const wrapper = cover.nextElementSibling; hide(wrapper); const player = createPlayer(wrapper, playerSettings); wrapper.player = player; } function createCoverClickHandler() { return function coverClickHandler(evt) { const cover = evt.currentTarget; const wrapper = cover.nextElementSibling; show(wrapper); const player = wrapper.player; player.setVolume(100); player.playVideo(); }; } function addPlayer(coverSelector, playerSettings) { // 预创建播放器 preCreatePlayer(coverSelector, playerSettings); const clickHandler = createCoverClickHandler(); 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" }); }
内容的提问来源于stack exchange,提问作者user16776772
相关产品推荐
相关产品推荐

