You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现仿YouTube的多视频鼠标悬停预览功能——解决仅首个视频生效及document.querySelectorAll无响应问题

解决多视频鼠标悬停预览失效问题

我明白你遇到的问题了——一开始只有第一个视频能触发预览,改成querySelectorAll后反而全失效了。这是因为querySelectorAll返回的是一个NodeList集合,你需要遍历每个视频元素,单独给它们绑定事件逻辑,而且每个视频得有自己的状态变量(比如预览超时器),不然多个视频会互相干扰。

下面是修改后的完整代码,我会一步步说明改动点:

核心改动说明

  • 把原来针对单个视频的逻辑,改成遍历所有视频元素,为每个视频单独处理
  • 将startPreview和stopPreview改成接受video参数的函数,让它们能操作当前触发事件的视频
  • 给每个视频绑定独立的超时器变量,避免不同视频的预览逻辑互相影响

修改后的HTML(和你的原代码一致,无需改动)

<div class="videos" onclick="location.href='video1.html'" style="cursor:pointer; position: relative;">
 <video>
 <source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm" />
 </video>
 <b>Video Title</b>
 <p>Video Description</p>
</div>
<div class="videos" onclick="location.href='video2.html'" style="cursor:pointer; position: relative;">
 <video>
 <source src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm" />
 </video>
 <b>Video Title 2</b>
 <p>Video Description 2</p>
</div>

修改后的JavaScript代码

function delay(milliseconds){
 return new Promise(resolve => {
 setTimeout(resolve, milliseconds);
 });
}

// 改成接受video参数的函数,操作传入的目标视频
async function startPreview(video) {
 await delay(300);
 video.muted = true;
 video.currentTime = 1;
 video.playbackRate = 0.5;
 video.play();
}

function stopPreview(video) {
 video.currentTime = 0;
 video.playbackRate = 1;
 video.pause();
}

// 获取所有视频元素,遍历处理每个视频
const videos = document.querySelectorAll("video");
videos.forEach(video => {
 // 每个视频单独维护自己的超时器变量
 let previewTimeout;

 video.addEventListener("mouseenter", async () => {
 await startPreview(video);
 // 4秒后自动停止预览
 previewTimeout = setTimeout(() => stopPreview(video), 4000);
 });

 video.addEventListener("mouseleave", () => {
 // 清除当前视频的超时器
 clearTimeout(previewTimeout);
 stopPreview(video);
 });
});

为什么这样改?

  • 原来的代码只操作了第一个video元素,所以只有第一个生效
  • 改成querySelectorAll后,必须遍历每个元素,给每个元素绑定独立的事件和状态
  • 每个视频的previewTimeout变量放在forEach的回调里,属于每个视频的独立作用域,不会和其他视频的超时器冲突
  • 把startPreview和stopPreview改成参数化函数,让它们能针对当前触发事件的视频进行操作,而不是固定操作某个全局的video变量

这样修改后,每个视频都会在鼠标悬停时独立触发预览,离开时停止,不会互相干扰啦。

内容的提问来源于stack exchange,提问作者Skyspartan149

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 14:52:42