多WordPress站点批量视频加载:单篇文章侧边栏脚本无法执行的修复求助
多WordPress站点批量视频加载:单篇文章侧边栏脚本无法执行的修复求助
看起来你已经精准定位了核心问题——单篇文章的侧边栏是动态加载的,当你的DOMContentLoaded事件触发时,侧边栏里的视频元素还没被渲染到DOM中,导致初始的脚本逻辑找不到元素,自然绑定不上事件。下面给你几个针对性的修复方案,你可以根据自己的场景尝试:
方案1:优化MutationObserver监听逻辑(推荐)
你的初始Observer只监听了#secondary,但如果这个侧边栏容器本身也是动态插入的,那初始的监听会直接失效。我们可以把监听范围扩大到整个文档,同时优化事件绑定避免重复触发:
<video id="video" width="100%" height="auto" poster="https://webtik.in/ads/cover.jpeg?nocache=<?php echo time(); ?>" controls style="display: none;"> <source id="videoSource" src="https://webtik.in/ads/video.mp4?nocache=<?php echo time(); ?>" type="video/mp4"> </video> <script> document.addEventListener('DOMContentLoaded', function () { // 封装视频初始化逻辑,复用+避免重复绑定 const checkAndInitializeVideo = () => { const video = document.getElementById('video'); const videoSource = document.querySelector('#video source'); if (video && videoSource) { // 先移除旧的事件监听,防止重复绑定 video.removeEventListener('loadedmetadata', showVideo); video.removeEventListener('error', hideVideo); videoSource.removeEventListener('error', hideVideo); // 定义显示/隐藏函数 function showVideo() { video.style.display = 'block'; } function hideVideo() { video.style.display = 'none'; } // 绑定新的事件监听 video.addEventListener('loadedmetadata', showVideo); video.addEventListener('error', hideVideo); videoSource.addEventListener('error', hideVideo); // 主动触发视频加载,解决动态插入元素不自动加载的问题 video.load(); } }; // 初始检查一次 checkAndInitializeVideo(); // 监听整个文档的DOM变化,确保侧边栏动态插入后能触发检查 const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { // 只有当有新节点插入时才检查,减少不必要的执行 if (mutation.addedNodes.length > 0) { checkAndInitializeVideo(); } }); }); observer.observe(document.body, { childList: true, subtree: true }); }); </script>
关键修改点:
- 把事件监听封装成独立函数,避免MutationObserver多次触发时重复绑定事件
- 主动调用
video.load(),强制视频开始加载(动态插入的视频元素有时不会自动触发加载流程) - 监听
document.body而非固定的#secondary,确保侧边栏容器本身动态插入后也能被监测到
方案2:使用轮询兜底(简单粗暴但有效)
如果MutationObserver的方式还是不生效,你可以试试用定时器轮询的方式,直到找到视频元素再初始化:
<video id="video" width="100%" height="auto" poster="https://webtik.in/ads/cover.jpeg?nocache=<?php echo time(); ?>" controls style="display: none;"> <source id="videoSource" src="https://webtik.in/ads/video.mp4?nocache=<?php echo time(); ?>" type="video/mp4"> </video> <script> document.addEventListener('DOMContentLoaded', function () { const checkAndInitializeVideo = () => { const video = document.getElementById('video'); const videoSource = document.querySelector('#video source'); if (video && videoSource) { // 绑定事件逻辑 video.addEventListener('loadedmetadata', () => { video.style.display = 'block'; }); video.addEventListener('error', () => { video.style.display = 'none'; }); videoSource.addEventListener('error', () => { video.style.display = 'none'; }); video.load(); // 找到元素后立即停止轮询,节省性能 clearInterval(pollTimer); } }; // 初始检查 checkAndInitializeVideo(); // 每500毫秒检查一次,可根据实际加载速度调整间隔 const pollTimer = setInterval(checkAndInitializeVideo, 500); }); </script>
注意事项:
- 不要把间隔设得太小,避免过多消耗浏览器性能
- 一定要在找到元素后清除定时器,防止无限循环
额外建议:WordPress插件层面调整
你用的是Advanced Ads插件的Widget来插入代码,可以试试:
- 在插件设置里把脚本的加载位置改成页脚(Footer),确保脚本在页面大部分元素渲染后执行
- 检查插件是否有「延迟加载」或「动态内容适配」的选项,开启后可能会自动适配动态加载的侧边栏
先试试方案1,它更符合现代前端的最佳实践,性能也更优。如果还是有问题,再用方案2兜底,或者调整插件的加载设置。
备注:内容来源于stack exchange,提问作者iamnareshsr




