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

组件中鼠标悬停播放视频仅触发DOM内最后一个视频的问题求助

解决鼠标悬停仅最后一个视频播放的问题

嘿,这个问题我太熟了——这是典型的var变量作用域+闭包陷阱!咱们来拆解下问题原因,再给你几个靠谱的解决方案:

问题根源

你用var声明了循环里的vid变量,而var是函数级作用域,整个videoPlays函数里只有一个vid变量。循环执行时,每次迭代都会把vid重新赋值为当前视频元素,但所有的mouseover/mouseout回调函数都是异步触发的——等你真正把鼠标放到视频上时,循环早就跑完了,vid已经被赋值成最后一个视频元素,所以所有回调都会操作最后那个视频。

解决方案

方案1:用let替代var(最简洁)

let是ES6引入的块级作用域变量,每次循环迭代都会创建一个新的vid变量,每个回调函数都会绑定当前迭代的那个视频元素:

document.addEventListener("DOMContentLoaded", videoPlays, false);
function videoPlays() {
  const videos: HTMLCollectionOf<Element> = document.getElementsByClassName("video");
  for(let i = 0; i < videos.length ; i++) { // 把var改成let
    const vid: HTMLVideoElement = videos[i] as HTMLVideoElement;
    vid.addEventListener("mouseover", () => { vid.play(); });
    vid.addEventListener("mouseout", () => { vid.pause(); });
  }
}

方案2:用forEach遍历(更优雅)

把HTMLCollection转成数组后用forEach遍历,每个回调函数都会拿到独立的视频元素引用,避免作用域问题:

document.addEventListener("DOMContentLoaded", videoPlays, false);
function videoPlays() {
  // 把HTMLCollection转成数组
  const videos = Array.from(document.getElementsByClassName("video")) as HTMLVideoElement[];
  videos.forEach(vid => {
    vid.addEventListener("mouseover", () => vid.play());
    vid.addEventListener("mouseout", () => vid.pause());
  });
}

方案3:用闭包创建独立作用域(兼容老环境)

如果需要兼容不支持ES6的环境,可以用立即执行函数表达式(IIFE)创建闭包,把当前视频元素封装到独立作用域里:

document.addEventListener("DOMContentLoaded", videoPlays, false);
function videoPlays() {
  var video: HTMLCollectionOf<Element> = document.getElementsByClassName("video");
  for(var i = 0; i < video.length ; i++) {
    // 用IIFE把当前视频元素作为参数传入,创建独立作用域
    (function(currentVid) {
      currentVid.addEventListener("mouseover", () => { currentVid.play(); });
      currentVid.addEventListener("mouseout", () => { currentVid.pause(); });
    })(video[i] as HTMLVideoElement);
  }
}

问题演示

问题演示GIF

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:22:32