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

鼠标悬停时元素位置异常 技术求助

视频播放器进度条悬停缩略图位置错误问题

我在制作一款练习用的简易视频播放器时,遇到了一个棘手的问题:鼠标悬停input进度条时,缩略图的位置出现偏移错误。经过数小时排查,发现是#time元素间接导致的,但我无法移除这个元素,且必须保持当前的div嵌套结构。移除#time后,悬停位置恢复正常,我怀疑这和flex属性、position属性有关,但尝试多种方法都没能解决。

预期效果是缩略图能精准跟随鼠标在进度条上的位置,当前问题可复现。

现有代码

HTML

<div class="container">
  <div id="core" class="core">
    <div id="time">01:14:28</div>
    <div id="progressZone">
      <input id="progress" class="range" type='range' min="0" max="100" step="0.01" value="0">
      <div id="thumbnail" class="thumbnail"></div>
    </div>
   </div>
</div>

CSS

body {
  overflow: hidden;
}

.container {
  width: 100%;
  max-width: 800px;
  position: relative;
  background-color: blue;
  height: 200px;
  overflow: hidden;
}

.core {
  margin: 0;
  display: flex;
  position: absolute;
  bottom: 4px;
  width: 100%;
  flex-wrap: nowrap;
  height: auto;
}

#time {
  font-size: 14px;
  text-shadow: 0 1px 1px rgb(0 0 0 / 15%);
  color: #fff;
  align-self: center;
  align-items: flex-start;
  margin: 0 12px;
  min-width: 45px;
  text-align: center;
}

#progressZone {
  width: 100%;
  background-color: green;
  position: relative;
}

#progress{
  z-index: 1;
  border-radius: 8px;
  height: 2px;
  width: 100%;
  outline: none;
  position: absolute;
  top: 0;
  bottom: 0;
  appearance: none;
  -webkit-appearance: none;
  margin: auto;
  background: transparent;
  margin-right: 10px;
}

.thumbnail {
  display: none;
  z-index: 1;
  position: absolute;
  bottom: 30px;
  right: auto;
  margin: 0;
  width: 12em;
  height: 7em;
  background: rgb(200, 200, 200);
  pointer-events: none;
  padding: 2px 2px;
  transform: translateX(-50%);
  left: 50%;
}

.thumbnail::before {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -8px;
  border: 8px solid transparent;
  border-top: 8px solid rgb(200, 200, 200);
  transform: translateY(-19%);
}

#progress:hover + .thumbnail {
  display: block;
}

JavaScript

var left = document.getElementById('core').getBoundingClientRect().left - document.documentElement.getBoundingClientRect().left;

window.onmousemove = function (e) {
  let x = ((e.clientX + window.pageXOffset) - left);
  document.getElementById("thumbnail").style.left = (x + "px");
}

问题原因分析

问题出在缩略图的定位基准和坐标计算上:

  • 缩略图是#progressZone下的绝对定位元素,它的left属性是相对于父元素#progressZone的左边界的。
  • 原JS代码计算的是鼠标相对于#core的位置,但#progressZone在flex容器中左侧有#time元素占据了一定宽度,导致计算出的x值比实际在#progressZone内的位置大,最终缩略图偏右。

修复方案

修改JavaScript代码,改为计算鼠标在#progressZone内的相对位置:

window.onmousemove = function (e) {
  const progressZone = document.getElementById('progressZone');
  const zoneRect = progressZone.getBoundingClientRect();
  // 计算鼠标在progressZone容器内的相对X坐标
  let x = e.clientX - zoneRect.left;
  // 限制x的范围,避免超出进度条区域
  x = Math.max(0, Math.min(x, zoneRect.width));
  document.getElementById("thumbnail").style.left = `${x}px`;
}

同时可以删除原代码中提前计算left变量的那一行,因为现在每次鼠标移动都会动态获取#progressZone的位置,即使窗口缩放也能保持准确。

这样修改后,缩略图就能精准跟随鼠标在进度条上的位置,不会再受#time元素的影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:40:47