鼠标悬停时元素位置异常 技术求助
视频播放器进度条悬停缩略图位置错误问题
我在制作一款练习用的简易视频播放器时,遇到了一个棘手的问题:鼠标悬停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
相关产品推荐
相关产品推荐

