如何在 Video.js 中为多个视频独立控制进度条的显示与隐藏

发布时间 - 2025-12-30 00:00:00    点击率:

本文详解如何使用 video.js 为不同视频(如 video1/video2)维护独立状态,实现在播放完成(100%)后才显示进度条,并避免变量作用域与事件绑定逻辑错误。

在 Video.js 中动态控制进度条(progressControl)的显隐,关键在于:状态需持久化、事件监听需正确绑定、且每个视频的状态必须相互隔离。你原始代码的核心问题并非语法错误,而是逻辑结构缺陷——video1 和 video2 被定义为函数局部变量,每次调用 light(Cvideo) 都会重新初始化为 false,导致 video1 = true 的赋值永远无法跨调用保留,自然无法触发后续的 show() 分支。

✅ 正确方案:使用闭包或外部状态管理

推荐将视频状态提升至全局作用域(或模块级),确保状态在多次调用间持续有效:

// 全局状态对象 —— 每个视频 ID 对应独立布尔标记
const videoStates = {
  1: false,
  2: false
};

function light(Cvideo) {
  const player = videojs("videoP");
  const videoSrc = Cvideo === 1 
    ? "video/1.mp4" 
    : "video/2.mp4";

  // 更新视频标题(可选)
  document.getElementById("nameV").textContent = Cvideo;

  // 重置进度显示
  document.getElementById("percentage").textContent = "0%";

  // 根据当前视频 ID 判断是否已播放完成过
  if (videoStates[Cvideo]) {
    player.controlBar.progressControl.show();
  } else {
    player.controlBar.progressControl.hide();

    // 绑定一次 timeupdate 监听器(防重复绑定!)
    const handleTimeUpdate = () => {
      const currentTime = player.currentTime();
      const duration = player.duration();

      if (duration && !isNaN(duration)) { // 确保 duration 可用
        const percentage = Math.round((currentTime / duration) * 100);
        document.getElementById("percentage").textContent = `${percentage}%`;

        if (percentage >= 99.9) { // 使用 >= 99.9 更鲁棒(浮点精度问题)
          videoStates[Cvideo] = true;
          player.controlBar.progressControl.show();
          player.off("timeupdate", handleTimeUpdate); // ✅ 移除监听,避免内存泄漏
        }
      }
    };

    player.on("timeupdate", handleTimeUpdate);
  }

  // 加载并播放新视频
  player.src({ type: "video/mp4", src: videoSrc });
  player.play();
}

⚠️ 关键注意事项

  • 避免重复绑定事件:每次调用 light() 都新增 timeupdate 监听器会导致多个监听器累积,引发性能问题和逻辑混乱。务必在满足条件后调用 player.off() 清理。
  • duration() 异步性:player.duration() 在元数据加载完成前可能返回 NaN 或 0,务必加 if (duration && !isNaN(duration)) 安全判断。
  • 100% 判定要宽容:由于浮点计算误差,percentage === 100 很难精确命中,建议改用 percentage >= 99.9。
  • CDN 资源引用:确保在 HTML 中正确引入 Video.js CSS 与 JS(版本建议 ≥7.20):
    
    

? 扩展建议(进阶)

若项目规模扩大,推荐封装为类或使用现代模块系统(ESM)管理状态:

class VideoProgressManager {
  constructor(playerId) {
    this.player = videojs(playerId);
    this.states = new Map(); // Map
  }
  showOnComplete(videoId, src) {
    if (this.states.get(videoId)) {
      this.player.controlBar.progressControl.show();
    } else {
      this.player.controlBar.progressControl.hide();
      const onTimeUpdate = () => { /* ... 同上逻辑 ... */ };
      this.player.on("timeupdate", onTimeUpdate);
      // 记得在完成时 this.states.set(videoId, true)
    }
    this.player.src({ type: "video/mp4", src });
  }
}

通过合理管理状态生命周期与事件绑定时机,即可实现多视频间完全独立的进度条行为控制——既符合用户体验(首次播放隐藏干扰项),又保障逻辑健壮性。


# css  # html  # js  # cdn  # 作用域  # .net  # if  # 封装  # 局部变量  # 变量作用域  # 闭包 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 大型企业网站制作流程,做网站需要注册公司吗?  如何在Windows 2008云服务器安全搭建网站?  Laravel定时任务怎么设置_Laravel Crontab调度器配置  如何在局域网内绑定自建网站域名?  北京网站制作的公司有哪些,北京白云观官方网站?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  C++时间戳转换成日期时间的步骤和示例代码  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  图册素材网站设计制作软件,图册的导出方式有几种?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  悟空浏览器如何设置小说背景色_悟空浏览器背景色设置【方法】  Laravel如何与Pusher实现实时通信?(WebSocket示例)  如何有效防御Web建站篡改攻击?  Laravel如何为API编写文档_Laravel API文档生成与维护方法  Laravel怎么调用外部API_Laravel Http Client客户端使用  宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  JavaScript如何操作视频_媒体API怎么控制播放  如何注册花生壳免费域名并搭建个人网站?  如何快速上传建站程序避免常见错误?  Laravel怎么连接多个数据库_Laravel多数据库连接配置  网站制作免费,什么网站能看正片电影?  千库网官网入口推荐 千库网设计创意平台入口  Laravel怎么实现模型属性的自动加密  焦点电影公司作品,电影焦点结局是什么?  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  如何基于PHP生成高效IDC网络公司建站源码?  零服务器AI建站解决方案:快速部署与云端平台低成本实践  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】  如何用西部建站助手快速创建专业网站?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤  JavaScript如何实现音频处理_Web Audio API如何工作?  用yum安装MySQLdb模块的步骤方法  高防服务器租用首荐平台,企业级优惠套餐快速部署  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环  如何快速生成凡客建站的专业级图册?  如何在自有机房高效搭建专业网站?  Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案  如何在万网自助建站平台快速创建网站?