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

HTML视频播放器进度条无法正常更新问题求助

视频进度条不更新的问题排查与修复

问题原因

  1. CSS与JS逻辑不匹配:你通过#progress-bar::before伪元素实现进度高亮效果,但JavaScript代码错误地修改了进度条容器(#progress-bar)的宽度,而非伪元素的宽度——容器本身应保持满宽,伪元素的宽度才是对应播放进度的部分。
  2. 未处理视频加载状态:视频未完全加载时video.duration为NaN,直接计算百分比会导致进度条无响应。

修复方案

1. 调整CSS样式

在原CSS基础上,给进度条容器添加CSS变量控制伪元素宽度,确保伪元素定位正确:

#progress-bar {
  flex-grow: 1;
  height: 5px;
  margin: 0 10px;
  position: relative;
  cursor: pointer;
  background-color: #555;
  width: 100%;
  /* 定义CSS变量控制进度宽度 */
  --progress-width: 0%;
}
#progress-bar::before {
  content: "";
  position: absolute;
  height: 100%;
  width: var(--progress-width);
  background-color: #fff;
  left: 0;
  top: 0;
}

2. 修改JavaScript关键函数

替换以下几个函数的逻辑,确保正确控制进度伪元素,并处理视频未加载的情况:

function updateProgressBar() {
  if (isNaN(video.duration)) return; // 视频未加载完成时跳过更新
  const percent = (video.currentTime / video.duration) * 100;
  // 通过CSS变量更新伪元素宽度
  progressBar.style.setProperty('--progress-width', percent + '%');
  currentTimeDisplay.textContent = formatTime(video.currentTime);
}

function seek(e) {
  if (isNaN(video.duration)) return; // 视频未加载时不响应点击
  const percent = e.offsetX / progressBar.clientWidth;
  video.currentTime = percent * video.duration;
}

function handleVideoEnd() {
  playPauseBtn.innerHTML = "►";
  // 重置进度伪元素宽度
  progressBar.style.setProperty('--progress-width', '0%');
  currentTimeDisplay.textContent = "0:00";
}

完整修复后代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Video Player</title>
    <style>
     body {
        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
        text-align: center;
        background-color: #222;
        margin: 0;
        padding: 0;
        color: #fff;
      }

      #video-container {
        max-width: 800px;
        margin: 20px auto;
        position: relative;
      }

      video {
        width: 100%;
        display: block;
      }

      #custom-controls {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        background-color: rgba(0, 0, 0, 0.7);
        display: flex;
        justify-content: space-between;
        padding: 10px;
        opacity: 0;
        transition: opacity 0.5s;
        box-sizing: border-box;
      }

      #video-container:hover #custom-controls {
        opacity: 1;
      }

      button,
      input {
        background: none;
        border: none;
        cursor: pointer;
        color: white;
        font-size: 16px;
        margin: 0 5px;
      }

      input[type="range"] {
        width: 150px;
      }

      #progress-bar-container {
        flex-grow: 1;
        display: flex;
        align-items: center;
      }

      #progress-bar {
        flex-grow: 1;
        height: 5px;
        margin: 0 10px;
        position: relative;
        cursor: pointer;
        background-color: #555;
        width: 100%;
        --progress-width: 0%;
      }
      #progress-bar::before {
        content: "";
        position: absolute;
        height: 100%;
        width: var(--progress-width);
        background-color: #fff;
        left: 0;
        top: 0;
      }
    </style>
  </head>
  <body>
    <div id="video-container">
      <video id="myVideo">
        <source src="1.mp4" type="video/mp4" />
        Your browser does not support the video tag.
      </video>
      <div id="custom-controls">
        <button id="playPauseBtn">&#9658;</button>
        <input
          type="range"
          id="volumeRange"
          min="0"
          max="1"
          step="0.1"
          value="1"
        />
        <span id="playbackSpeed">Speed: 1x</span>
        <input
          type="range"
          id="speedRange"
          min="0.5"
          max="2"
          step="0.1"
          value="1"
        />
        <button id="muteBtn">Mute 🔇</button>
        <div id="progress-bar-container">
          <span id="current-time">0:00</span>
          <div id="progress-bar"></div>
          <span id="duration">0:00</span>
        </div>
        <button id="fullscreenBtn">Full</button>
      </div>
    </div>

    <script>
      const video = document.getElementById("myVideo");
      const playPauseBtn = document.getElementById("playPauseBtn");
      const volumeRange = document.getElementById("volumeRange");
      const speedRange = document.getElementById("speedRange");
      const playbackSpeedDisplay = document.getElementById("playbackSpeed");
      const muteBtn = document.getElementById("muteBtn");
      const progressBar = document.getElementById("progress-bar");
      const currentTimeDisplay = document.getElementById("current-time");
      const durationDisplay = document.getElementById("duration");
      const fullscreenBtn = document.getElementById("fullscreenBtn");

      playPauseBtn.addEventListener("click", togglePlayPause);
      volumeRange.addEventListener("input", setVolume);
      speedRange.addEventListener("input", setSpeed);
      muteBtn.addEventListener("click", toggleMute);
      progressBar.addEventListener("click", seek);
      fullscreenBtn.addEventListener("click", toggleFullscreen);
      video.addEventListener("timeupdate", updateProgressBar);
      video.addEventListener("durationchange", updateDuration);
      video.addEventListener("ended", handleVideoEnd);

      function togglePlayPause() {
        if (video.paused) {
          video.play();
          playPauseBtn.innerHTML = "❚❚";
        } else {
          video.pause();
          playPauseBtn.innerHTML = "&#9658;";
        }
      }

      function setVolume() {
        video.volume = volumeRange.value;
        if (video.volume === 0) {
          muteBtn.innerHTML = "Unmute 🔊";
        } else {
          muteBtn.innerHTML = "Mute 🔇";
        }
      }

      function setSpeed() {
        video.playbackRate = speedRange.value;
        playbackSpeedDisplay.textContent = `Speed: ${speedRange.value}x`;
      }

      function toggleMute() {
        video.muted = !video.muted;
        if (video.muted) {
          muteBtn.innerHTML = "Unmute 🔊";
        } else {
          muteBtn.innerHTML = "Mute 🔇";
        }
      }

      function toggleFullscreen() {
        if (video.requestFullscreen) {
          video.requestFullscreen();
        } else if (video.mozRequestFullScreen) {
          video.mozRequestFullScreen(); 
        } else if (video.webkitRequestFullscreen) {
          video.webkitRequestFullscreen();
        }
      }

      function seek(e) {
        if (isNaN(video.duration)) return;
        const percent = e.offsetX / progressBar.clientWidth;
        video.currentTime = percent * video.duration;
      }

      function updateProgressBar() {
        if (isNaN(video.duration)) return;
        const percent = (video.currentTime / video.duration) * 100;
        progressBar.style.setProperty('--progress-width', percent + '%');
        currentTimeDisplay.textContent = formatTime(video.currentTime);
      }

      function updateDuration() {
        durationDisplay.textContent = formatTime(video.duration);
      }

      function formatTime(time) {
        const minutes = Math.floor(time / 60);
        const seconds = Math.floor(time % 60);
        return `${minutes}:${seconds < 10 ? "0" : ""}${seconds}`;
      }

      function handleVideoEnd() {
        playPauseBtn.innerHTML = "&#9658;";
        progressBar.style.setProperty('--progress-width', '0%');
        currentTimeDisplay.textContent = "0:00";
      }
    </script>
  </body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:48:12