问题描述
ja实现目标元素的自由拖拽效果,当鼠标移动过快,会造成鼠标脱离目标元素外(脱标)从而导致拖拽失效。
问题分析
鼠标移动过快,导致mousemove事件
频繁触发,相应的事件处理函数也频繁调用,引起延迟。延迟过后由于元素的移动速度不及鼠标的移动速度,造成鼠标移动到元素外,从而触发mouseout事件
,提前结束拖拽。
优化方案
将事件处理函数添加到 document 上,而非目标元素上,让 mousemove事件
在有延迟的情况下仍然可以被响应即可。
将事件绑定到 document 和 body 上的区别:绑定到 document 上,当鼠标移动到菜单栏(边界)上,元素仍然可以拖动,而 body 则无效。
完整案例
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#draggableBox {
width: 100px;
height: 100px;
position: absolute;
cursor: grab;
z-index: 98;
border-radius: 50%;
background-color: skyblue;
top: 80%;
left: 80%;
}
</style>
</head>
<body>
<div id="draggableBox" draggable="true"></div>
<script>
const draggableElement = document.getElementById('draggableBox');
let offsetX, offsetY;
draggableElement.addEventListener('mousedown', dragMouseDown);
draggableElement.addEventListener('mouseup', stopDrag);
function dragMouseDown(e) {
e.preventDefault();
offsetX = e.clientX;
offsetY = e.clientY;
document.addEventListener('mousemove', elementDrag);
}
function elementDrag(e) {
e.preventDefault();
const x = offsetX - e.clientX;
const y = offsetY - e.clientY;
offsetX = e.clientX;
offsetY = e.clientY;
draggableElement.style.top = (draggableElement.offsetTop - y) + 'px';
draggableElement.style.left = (draggableElement.offsetLeft - x) + 'px';
}
function stopDrag() {
document.removeEventListener('mousemove', elementDrag);
}
</script>
</body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。