如何获取相同类名的不同元素位置?mousemove仅获首个位置导致重叠
问题根因
现有代码的核心问题是:每次mousemove事件触发遍历.img-box元素时,都会实时读取当前元素的offset().left和offset().top,但上一轮事件触发或者上一个元素的遍历已经修改了元素的left、top属性,导致读取到的坐标是偏移后的动态值,而非元素的初始位置。所有元素的坐标会随着鼠标移动逐步趋同,最终重叠。
优化方案
优化核心是提前缓存所有.img-box的初始坐标,后续鼠标移动时直接调用缓存值计算偏移,不要每次动态读取实时坐标。
优化后代码如下:
// 页面初始化阶段缓存所有img-box的初始坐标,仅执行一次 const initPositions = [] $('.img-box').each(function(index) { initPositions[index] = { x: $(this).offset().left / 100, y: $(this).offset().top / 100 } }) $(window).mousemove(function(evt){ // 鼠标偏移量提取到遍历外,仅计算一次 const mouseOffsetX = evt.pageX / 100 const mouseOffsetY = evt.pageY / 100 $('.img-box').each(function(index){ // 基于固定初始坐标计算偏移,不受上一次位置影响 $(this).css({ left: initPositions[index].x + mouseOffsetX + "%", top: initPositions[index].y + mouseOffsetY + "%" }) }) })
优化说明
- 仅在页面初始化时读取一次所有元素的初始坐标,避免频繁读取DOM属性带来的性能损耗
- 每个元素的偏移计算基于自身固定的初始坐标,不会因为其他元素的位置修改或者上一次偏移的结果影响计算逻辑,彻底解决重叠问题
- 鼠标偏移量的计算提取到遍历逻辑外,减少重复计算量
内容的提问来源于stack exchange,提问作者Penny Chang
相关产品推荐
相关产品推荐

