Как поймать событие mouse-up вне элемента?
У меня есть простой код на JavaScript, похожий на следующий:
var mouseIsDown = false;
// ...
function canvasMouseDown(e) {
// ...
mouseIsDown = true;
}
function canvasMouseUp(e) {
mouseIsDown = false;
}
function canvasMouseMove(e) {
if (mouseIsDown) {
// ...
}
}
Я реализую собственный пользовательский интерфейс для трансформаций (перемещения, масштабирования и вращения) с помощью <canvas>
.
В данной реализации функция canvasMouseMove()
проверяет переменную mouseIsDown
. Все работает хорошо, пока пользователь не отпустит кнопку мыши, когда курсор находится вне элемента <canvas>
. В этом случае переменная mouseIsDown
остается true
, и функция canvasMouseUp
не срабатывает.
Каков простой способ или решение для этой проблемы на чистом JavaScript (без jQuery)?
5 ответ(ов)
Ваш код добавляет обработчик события mouseup
, который срабатывает, когда пользователь отпускает кнопку мыши. Этот обработчик будет вызываться не только когда пользователь отпускает кнопку мыши внутри окна браузера, но и когда он делает это вне его. Это означает, что вы можете отслеживать события мыши даже если курсор находится за пределами окна браузера.
Вот пример, как это работает:
window.addEventListener('mouseup', function(event) {
// Ваша логика здесь
console.log('Кнопка мыши отпущена', event);
});
Важно отметить, что в зависимости от специфики задачи, вы можете использовать дополнительные методы и свойства объекта события для получения более детальной информации о событии, например, event.clientX
и event.clientY
для получения координат курсора мыши.
Вопрос: Почему событие mouseup
на документе срабатывает даже вне области просмотра?
Ответ: Событие mouseup
, привязанное к объекту document
, действительно срабатывает вне области просмотра (viewport), и это интересный момент, который можно узнать, только работая с документом. В приведенном вами примере:
$(document).mouseup(function(e){
alert("UP" + e.pageX);
});
Событие mouseup
обрабатывается даже тогда, когда курсор мыши находится вне видимой части окна браузера. Это поведение связано с тем, что document
охватывает всю страницу, а не только её видимую часть.
В результате, когда вы отпускаете кнопку мыши, например, на другом экране или вне области браузера, события все равно будут зарегистрированы, если они происходят над document
. Кроме того, вы также получите информацию о позиции курсора, как видно из свойства e.pageX
. Это может быть полезно в некоторых сценариях, например, для создания расширенного функционала взаимодействия с пользователем.
Вы можете протестировать это поведение по следующей ссылке: http://jsfiddle.net/G5Xr2/.
В JavaScript это будет выглядеть следующим образом:
myElement.addEventListener('mousedown', () => {
const handleMouseUp = (event) => {
// проверяем, произошло ли событие вне элемента, сравнивая event.target и myElement
document.removeEventListener('mouseup', handleMouseUp);
};
document.addEventListener('mouseup', handleMouseUp);
});
Здесь мы добавляем обработчик события mousedown
к элементу myElement
. Когда происходит нажатие кнопки мыши, создается функция handleMouseUp
, которая будет срабатывать на событии mouseup
. Внутри этой функции мы можем проверить, произошло ли событие mouseup
вне нашего элемента. После этого мы удаляем обработчик события mouseup
, чтобы избежать возможных утечек памяти.
Для решения вашей задачи, вы можете добавить обработчик события mouseUp
на более высоком уровне, например, на элемент body
. Это позволит вам следить за состоянием мыши и устанавливать переменную mouseIsDown
в false
, когда происходит событие mouseUp
. Вот пример кода:
let mouseIsDown = false;
document.addEventListener('mousedown', function() {
mouseIsDown = true;
});
document.addEventListener('mouseup', function() {
mouseIsDown = false;
});
// Обработчик для демонстрации
document.addEventListener('mousemove', function(event) {
if (mouseIsDown) {
console.log(`Mouse is moving at (${event.clientX}, ${event.clientY}) while mouse is down.`);
}
});
В этом примере мы добавляем обработчик mousemove
, который проверяет состояние mouseIsDown
. Когда происходит нажатие мыши (mousedown
), мы устанавливаем mouseIsDown
в true
, и когда происходит отпускание (mouseup
), возвращаем его в false
. Это позволит вам отслеживать движения мыши только при удержании кнопки.
Если вам нужна полная демонстрация, вот ссылка на jsFiddle: http://jsfiddle.net/ZFefV/.
Современный правильный ответ, похоже, заключается в использовании метода setPointerCapture
:
https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture
Этот метод позволяет вам получать, например, координаты мыши даже тогда, когда указатель находится за пределами окна браузера (включая событие mouseup
, конечно).
Где найти документацию по форматированию даты в JavaScript?
Как определить нажатие клавиши Esc?
Как проверить, содержит ли массив строку в TypeScript?
Ссылка и выполнение внешнего JavaScript-файла, размещенного на GitHub
Как остановить Babel от трансформации 'this' в 'undefined' и добавления "use strict"