画布元素拖拽时定位偏移如何解决?
在实现画布元素拖拽功能时,发现元素移动过程中定位总是偏移大概20px左右,调试半天没找到原因。我用mousedown记录初始位置,mousemove实时更新top/left,但实际位置不对:
let startX, startY;
element.addEventListener('mousedown', (e) => {
startX = e.clientX;
startY = e.clientY;
});
document.addEventListener('mousemove', (e) => {
const x = e.clientX - startX;
const y = e.clientY - startY;
element.style.left = <code>${element.offsetLeft + x}px</code>;
element.style.top = <code>${element.offsetTop + y}px</code>;
});
尝试过用pageX代替clientX,调整过父容器的transform属性,但问题依旧存在。请问这种定位偏移通常是什么原因导致的?应该怎么修正?
element.offsetLeft + x和element.offsetTop + y来更新位置,但这里的offsetLeft和offsetTop是元素相对于父容器的位置,而e.clientX和e.clientY是鼠标相对于视口的位置,两者的参考系不一致,所以会导致定位偏移。正确的做法是,在mousedown的时候不仅记录鼠标的初始位置,还要记录元素的初始位置,然后在mousemove里直接用鼠标移动的距离加上元素的初始位置来计算新的位置。
给你一个改好的代码示例:
这里的关键点有两个:一是mousedown时记录元素的初始位置,二是mousemove里用初始位置加鼠标移动的距离来更新元素位置,而不是每次都叠加
offsetLeft和offsetTop。另外提醒一下,记得给拖拽元素加上
position: absolute;样式,否则top和left不会生效。还有,拖拽过程中如果页面有滚动条,最好用e.pageX和e.pageY代替e.clientX和e.clientY,因为pageX和pageY会自动考虑滚动偏移。最后吐槽一句,这种偏移问题真的挺烦人的,尤其是调试的时候发现怎么调都不对,后来才发现是参考系搞错了。希望你能少走点弯路吧。