如何处理不触发 mousemove 事件的快速移动鼠标
How to handle fast moving mouse which doesn't trigger mousemove event
我正在尝试使用鼠标事件和绝对定位为元素创建简单的拖动行为。
我有一个容器 div 的 mousemove
事件侦听器,它在 clientX
和 clientY
属性的帮助下更改了 boxRef
的位置鼠标事件。
鼠标移动慢的时候还可以,快的时候就停了,
我该如何处理这个问题,以便无论鼠标移动速度如何,元素都不会停止?
const shadowStytle = "10px 10px 12px #888888";
const appRef = document.getElementById('app');
appRef.innerHTML = `<div class="box" id="box"></div>`;
const boxRef = document.getElementById("box");
const xOffset = boxRef.clientWidth / 2;
const yOffset = boxRef.clientHeight / 2;
let selectionLocked = false;
function lockSelection() {
selectionLocked = true;
boxRef.style.boxShadow = shadowStytle;
boxRef.style.backgroundColor = "red";
}
function unlockSelection() {
selectionLocked = false;
boxRef.style.boxShadow = "none";
boxRef.style.backgroundColor = "black";
}
unlockSelection();
boxRef.addEventListener("mousedown", (arg) => {
lockSelection();
});
boxRef.addEventListener("mouseup", (arg) => {
unlockSelection();
});
boxRef.addEventListener("mouseleave", (arg) => {
if (selectionLocked) {
selectionLocked = false;
boxRef.style.boxShadow = "none";
}
});
appRef.addEventListener("mousemove", (arg) => {
if (selectionLocked) {
boxRef.style.left = `${arg.clientX - xOffset}px`;
boxRef.style.top = `${arg.clientY - yOffset}px`;
}
});
.box {
position: absolute;
border: 1px solid black;
padding: 25px;
width: 10%;
}
<div id="app"></div>
Stackblitz
元素上不需要 mouseleave
。您的问题是 mouseleave
在元素上触发并终止了拖动。相反,利用事件冒泡并将您的处理程序添加到 足够大的父容器 或 window
本身。在 window/container 上启动 mouseup
当且仅当 它已被 mousedown
previoulsy 激活。如果你愿意,如果你想节省一些计算,你也可以 删除并重新附加 window 上 mousedown
上的处理程序。但是我离开了它:
https://jsfiddle.net/ibowankenobi/gd1e93a3/1/
const shadowStytle = "10px 10px 12px #888888";
const appRef = document.getElementById('app');
appRef.innerHTML = `<div class="box" id="box"></div>`;
const boxRef = document.getElementById("box");
const xOffset = boxRef.clientWidth / 2;
const yOffset = boxRef.clientHeight / 2;
let selectionLocked = false;
function lockSelection() {
selectionLocked = true;
boxRef.style.boxShadow = shadowStytle;
boxRef.style.backgroundColor = "red";
}
function unlockSelection() {
selectionLocked = false;
boxRef.style.boxShadow = "none";
boxRef.style.backgroundColor = "black";
}
unlockSelection();
boxRef.addEventListener("mousedown", (arg) => {
lockSelection();
});
window.addEventListener("mouseup", (arg) => {
selectionLocked && unlockSelection();
});
boxRef.addEventListener("mouseleave", (arg) => {
/*if (selectionLocked) {
selectionLocked = false;
boxRef.style.boxShadow = "none";
}*/
});
window.addEventListener("mousemove", (arg) => {
if (selectionLocked) {
boxRef.style.left = `${arg.clientX - xOffset}px`;
boxRef.style.top = `${arg.clientY - yOffset}px`;
}
});
我正在尝试使用鼠标事件和绝对定位为元素创建简单的拖动行为。
我有一个容器 div 的 mousemove
事件侦听器,它在 clientX
和 clientY
属性的帮助下更改了 boxRef
的位置鼠标事件。
鼠标移动慢的时候还可以,快的时候就停了, 我该如何处理这个问题,以便无论鼠标移动速度如何,元素都不会停止?
const shadowStytle = "10px 10px 12px #888888";
const appRef = document.getElementById('app');
appRef.innerHTML = `<div class="box" id="box"></div>`;
const boxRef = document.getElementById("box");
const xOffset = boxRef.clientWidth / 2;
const yOffset = boxRef.clientHeight / 2;
let selectionLocked = false;
function lockSelection() {
selectionLocked = true;
boxRef.style.boxShadow = shadowStytle;
boxRef.style.backgroundColor = "red";
}
function unlockSelection() {
selectionLocked = false;
boxRef.style.boxShadow = "none";
boxRef.style.backgroundColor = "black";
}
unlockSelection();
boxRef.addEventListener("mousedown", (arg) => {
lockSelection();
});
boxRef.addEventListener("mouseup", (arg) => {
unlockSelection();
});
boxRef.addEventListener("mouseleave", (arg) => {
if (selectionLocked) {
selectionLocked = false;
boxRef.style.boxShadow = "none";
}
});
appRef.addEventListener("mousemove", (arg) => {
if (selectionLocked) {
boxRef.style.left = `${arg.clientX - xOffset}px`;
boxRef.style.top = `${arg.clientY - yOffset}px`;
}
});
.box {
position: absolute;
border: 1px solid black;
padding: 25px;
width: 10%;
}
<div id="app"></div>
Stackblitz
元素上不需要 mouseleave
。您的问题是 mouseleave
在元素上触发并终止了拖动。相反,利用事件冒泡并将您的处理程序添加到 足够大的父容器 或 window
本身。在 window/container 上启动 mouseup
当且仅当 它已被 mousedown
previoulsy 激活。如果你愿意,如果你想节省一些计算,你也可以 删除并重新附加 window 上 mousedown
上的处理程序。但是我离开了它:
https://jsfiddle.net/ibowankenobi/gd1e93a3/1/
const shadowStytle = "10px 10px 12px #888888";
const appRef = document.getElementById('app');
appRef.innerHTML = `<div class="box" id="box"></div>`;
const boxRef = document.getElementById("box");
const xOffset = boxRef.clientWidth / 2;
const yOffset = boxRef.clientHeight / 2;
let selectionLocked = false;
function lockSelection() {
selectionLocked = true;
boxRef.style.boxShadow = shadowStytle;
boxRef.style.backgroundColor = "red";
}
function unlockSelection() {
selectionLocked = false;
boxRef.style.boxShadow = "none";
boxRef.style.backgroundColor = "black";
}
unlockSelection();
boxRef.addEventListener("mousedown", (arg) => {
lockSelection();
});
window.addEventListener("mouseup", (arg) => {
selectionLocked && unlockSelection();
});
boxRef.addEventListener("mouseleave", (arg) => {
/*if (selectionLocked) {
selectionLocked = false;
boxRef.style.boxShadow = "none";
}*/
});
window.addEventListener("mousemove", (arg) => {
if (selectionLocked) {
boxRef.style.left = `${arg.clientX - xOffset}px`;
boxRef.style.top = `${arg.clientY - yOffset}px`;
}
});