Alpine.js构建的模态框在Firefox生产环境需刷新页面才可自动播放视频的问题求助
Alpine.js构建的模态框在Firefox生产环境需刷新页面才可自动播放视频的问题求助
大家好,我遇到了一个挺棘手的兼容性问题,想请教下各位大佬:
我用Alpine.js在页面上做了一个模态框,点击“See how it works”按钮后,模态框弹出,里面的视频应该自动开始播放;点击模态框外部或者“Close video”按钮可以关闭模态框。
这个功能在Chrome、Safari不管是本地还是生产环境都完全正常,Firefox本地测试也没问题,但到了Firefox的生产环境,视频就是不会自动播放——模态框能正常打开关闭,但视频毫无反应,除非我刷新页面,之后再打开模态框视频才会正常自动播放。
有没有什么特定的处理方式,能让Firefox生产环境下不用刷新页面也能正常加载并自动播放视频呢?
下面是我这个模块的代码:
HTML代码
<div class="section-how-it-works" x-ignore ax-load x-data="{ modalOpen: false }"> <div x-ignore ax-load x-data="VideoModal"> <!-- how it works video button --> <button id="open-modal-button" class="button button-secondary" aria-label="See how it works" @click="modalOpen = true" aria-controls="modal" > <span class="text">See how it works</span> <span class="icon"> <Icon name="video-play" size="16" /> </span> </button> <!-- how it works modal backdrop --> <div class="modal-backdrop" x-show="modalOpen" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="transition ease-out duration-100" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" aria-hidden="true" x-cloak ></div> <!-- how it works video modal --> <div id="modal" role="dialog" aria-modal="true" x-show="modalOpen" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 scale-75" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-out duration-200" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-75" x-cloak x-cloak > <!-- video --> <div class="video" x-data="{ play: true, mute: false, subtitles: false }" x-init="$refs.video.onplaying = () => { play = true }; $refs.video.onended = () => { play = false }; $watch('play', (value) => { if (value) { $refs.video.play(); } else { $refs.video.pause(); } })"> <figure class="video-inner" @click.outside="modalOpen = false" @keydown.escape.window="modalOpen = false"> <video id="how-it-works-video" x-ignore ax-load="lazy" playsinline x-init="$watch('modalOpen', value => value ? $el.play() : $el.pause())" x-ref="video" @click="play = !play"> <source src={howItWorksVideo} type="video/mp4"/> <track label="English" kind="subtitles" src={subs} srclang="en" x-show="subtitles" x-bind:default="subtitles"> </video> <!-- Video controls --> <div id="video-controls" class="controls" data-state="hidden"> <div @click="play = !play"> <template x-if="!play"> <Icon name="vid-play" class="control"/> </template> <template x-if="play"> <Icon name="vid-pause" class="control"/> </template> </div> <button class="progress" class="control"> <progress id="progress" value="0" min="0"> <span id="progress-bar"></span> </progress> </button> <div @click="mute = !mute; $refs.video.muted = mute" class="mute"> <template x-if="!mute"> <Icon name="vol-on" class="control"/> </template> <template x-if="mute"> <Icon name="vol-off" class="control"/> </template> </div> <div @click="subtitles = !subtitles; $refs.video.textTracks[0].mode = subtitles ? 'showing' : 'hidden'" class="subtitles"> <div x-show="!subtitles" class="tooltip"> <Icon name="subs-off" class="control"/> <span class="tooltiptext">Enable captions</span> </div> <div x-show="subtitles" class="tooltip"> <Icon name="subs-on" class="control"/> </div> </div> </div> <!-- End of video controls --> </figure> </div> <!-- close button --> <button id="close-modal-button" class="button button-secondary" @click="modalOpen = false" aria-label="Close video"> <span class="text">Close video</span> <span class="icon"> <Icon name="close" size="16" /> </span> </button> </div> </div> </div>
JS代码
export default () => { return { init() { const heroVideo = document.getElementById('hero-video'); const openModalButton = document.getElementById('open-modal-button'); const closeModalButton = document.getElementById('close-modal-button'); const modal = document.getElementById('modal'); const header = document.getElementById('header'); const disableScroll = () => { document.body.style.overflow = 'hidden'; document.addEventListener('touchmove', preventScroll, { passive: false }); }; const enableScroll = () => { document.body.style.overflow = 'auto'; document.removeEventListener('touchmove', preventScroll, { passive: false }); }; const preventScroll = (event) => { event.preventDefault(); }; //Open modal openModalButton.addEventListener('click', () => { heroVideo.pause(); modal.classList.add('open'); header.style.zIndex = '30'; disableScroll(); const video = document.getElementById("how-it-works-video"); const progress = document.getElementById("progress"); const progressBar = document.getElementById("progress-bar"); // Ensuring progress bar reflects video duration video.addEventListener("loadedmetadata", () => { progress.setAttribute("max", video.duration); }); // Progress bar update to reflect current position in video video.addEventListener("timeupdate", () => { if (!progress.getAttribute("max")) { progress.setAttribute("max", video.duration); } progress.value = video.currentTime; progressBar.style.width = `${Math.floor((video.currentTime * 100) / video.duration)}%`; }); // Allowing users to interact with progress bar / seek specific point in video progress.addEventListener("click", (e) => { const rect = progress.getBoundingClientRect(); const pos = (e.pageX - rect.left) / progress.offsetWidth; video.currentTime = pos * video.duration; }); }); //Close modal through close button closeModalButton.addEventListener('click', () => { heroVideo.play(); modal.classList.remove('open'); header.style.zIndex = '100'; enableScroll(); }); //Close modal with click outside of modal area modal.addEventListener('click', (event) => { if (event.target === modal) { heroVideo.play(); modal.classList.remove('open'); header.style.zIndex = '100'; enableScroll(); } }); //Close modal by pressing ESC document.addEventListener('keydown', (event) => { if (event.key === 'Escape' && modal.classList.contains('open')) { heroVideo.play(); modal.classList.remove('open'); header.style.zIndex = '100'; enableScroll(); } }); }, }; };
我自己初步猜是不是Firefox生产环境下的视频预加载或者Alpine的初始化时机问题?比如视频还没加载完成就触发了play(),但本地环境资源加载快所以没问题?或者是ax-load的lazy加载在Firefox生产下有延迟?
有没有大佬遇到过类似的情况,给点思路或者解决方案呀,万分感谢!
备注:内容来源于stack exchange,提问作者scubaM
相关产品推荐
相关产品推荐

