如果在触发鼠标按钮的元素之外释放鼠标按钮,则不会触发事件。
这会导致JQuery UI中的拖放错误:当鼠标按钮被释放到容器外时,JQuery 拖曳元素不会停止拖动(因为该元素在到达其父边界时将停止移动)。复制步骤:
我在最新的Chrome和IE中看到了这种行为。
有什么解决办法吗?
我知道我们可以停止在mouseout或mouseleave上拖动容器,但是我想继续拖动,即使我在父容器之外,就像在谷歌地图中一样(不管您在哪里释放鼠标,它总是停止拖动映射)。
发布于 2022-03-28 07:48:21
您可以让鼠标向下的元素“捕获”指针。然后它将始终接收mouseup事件。在“反应”中,这可能是这样的:
const onPointerDownDiv1 = (event: React.PointerEvent) => {
(event.target as HTMLDivElement).setPointerCapture(event.pointerId);
// Do something ...
};
const onPointerUpDiv1 = (event: React.PointerEvent) => {
(event.target as HTMLDivElement).releasePointerCapture(event.pointerId);
// Do something ...
};<div
ref={div1}
id="div1"
className="absolute top-[200px] left-[390px] h-8 w-8 bg-red-300"
onPointerDown={onPointerDownDiv1}
onPointerUp={onPointerUpDiv1}
/>下面是一个使用“纯香草”html +javascript的实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<div
id="div1"
style="
position: absolute;
left: 50px;
top: 50px;
width: 20px;
height: 20px;
background-color: red;
"
></div>
</body>
<script>
let isDragging = false;
let offsetX = 0;
let offsetY = 0;
let divElement = document.getElementById("div1");
divElement.addEventListener("pointerdown", onPointerDown);
divElement.addEventListener("pointermove", onPointerMove);
divElement.addEventListener("pointerup", onPointerUp);
function onPointerDown(event) {
divElement.setPointerCapture(event.pointerId);
offsetX = event.clientX - divElement.offsetLeft;
offsetY = event.clientY - divElement.offsetTop;
isDragging = true;
}
function onPointerMove(event) {
if (isDragging) {
divElement.style.left = (event.clientX - offsetX).toString() + "px";
divElement.style.top = (event.clientY - offsetY).toString() + "px";
}
}
function onPointerUp(event) {
divElement.releasePointerCapture(event.pointerId);
isDragging = false;
}
</script>
</html>发布于 2014-01-12 11:11:41
我发现这是最好的解决方案:将mouseup事件处理程序附加到document。然后,它将永远取消,即使您释放鼠标按钮外的浏览器。当然,这不是一个很好的解决方案,但显然,这是唯一的方法,以获得正确的拖动工作。
尝试下面的解决方案:
let dragging = false;
const dragEl = document.querySelector('div');
const logEl = document.querySelector('pre');
dragEl.addEventListener('mousedown touchstart', (evt) => {
dragging = true;
dragEl.classList.add('unselectable');
logEl.textContent += 'drag START\n';
});
document.addEventListener('mouseup touchend', (evt) => {
if (dragging) {
event.preventDefault();
dragEl.classList.remove('unselectable');
dragging = false;
logEl.textContent += 'drag END\n';
}
});div {
background: red;
}
.unselectable {
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+/Edge */
user-select: none; /* Standard */
}<div>drag me</div>
<hr>
LOG:
<p><pre></pre></p>
更新
发布于 2014-12-03 16:30:38
处理此问题的最佳方法是检查mousemove事件处理程序中的当前按钮状态。如果按钮不再按下,请停止拖动。
如果您将mouseup事件放在文档上,那么您只需将问题向上移动,如果您在文档之外(甚至在浏览器窗口之外)释放按钮,那么原始问题仍然会显示出来。
例如,使用jQuery
$div.on("mousedown", function (evt) {
dragging = true;
}).on("mouseup", function (evt) {
dragging = false;
}).on("mousemove", function (evt) {
if (dragging && evt.button == 0) {
//Catch case where button released outside of div
dragging = false;
}
if (dragging) {
//handle dragging here
}
});您可以跳过mouseup事件处理程序,因为它将被mousemove捕获,但是我认为它仍然存在,因此更容易读懂。
https://stackoverflow.com/questions/21073863
复制相似问题