Книга: Выразительный JavaScript
Движение мыши
Движение мыши
Каждый раз при сдвиге курсора мыши запускается событие "mousemove"
. Его можно использовать для отслеживания позиции мыши. Обычно это нужно при создании некоей функциональности, связанной с перетаскиванием объектов мышью.
К примеру, следующая программа отображает полоску и устанавливает обработку событий так, что движение влево и вправо уменьшает или увеличивает её ширину.
<p>Переместите мышь для увеличения ширины:</p>
<div>
</div>
<script>
var lastX; // Последняя позиция мыши
var rect = document.querySelector("div");
rect.addEventListener("mousedown", function(event) {
if (event.which == 1) {
lastX = event.pageX;
addEventListener("mousemove", moved);
event.preventDefault(); // Запретим выделение
}
});
function moved(event) {
if (event.which != 1) {
removeEventListener("mousemove", moved);
} else {
var dist = event.pageX - lastX;
var newWidth = Math.max(10, rect.offsetWidth + dist);
rect.style.width = newWidth + "px";
lastX = event.pageX;
}
}
</script>
Обратите внимание – обработчик "mousemove"
зарегистрирован у всего окна. Даже если мышь уходит за пределы полоски, нам надо обновлять её размер и прекращать это, когда кнопку отпускают.
Когда курсор попадает на узел и уходит с него, происходят события "mouseover"
или "mouseout"
. Их можно использовать, кроме прочего, для создания эффектов проведения мыши, показывая или меняя стиль чего-либо, когда курсор находится над этим элементом.
К сожалению, создание такого эффекта не ограничивается запуском его при событии "mouseover"
и завершением при событии "mouseout"
. При движении мыши от узла к его дочерним узлам на родительском узле происходит событие "mouseout"
, хотя мышь, вообще говоря, его и не покидала. Что ещё хуже, эти события распространяются как и все другие, поэтому вы всё равно получаете "mouseout"
при уходе курсора с одного их дочерних узлов того узла, где вы зарегистрировали обработчик.
Для обхода проблемы можно использовать свойство relatedTarget
объекта событий. Он сообщает, на каком узле была до этого мышь при возникновении события "mouseover"
, и на какой элемент она переходит при событии "mouseout"
. Нам надо менять эффект, только когда relatedTarget
находится вне нашего целевого узла. Только в этом случае событие на самом деле представляет собой переход на наш узел (или уход с узла).
<p>Наведите мышь на этот <strong>параграф </strong>.</p>
<script>
var para = document.querySelector("p");
function isInside(node, target) {
for (; node != null; node = node.parentNode)
if (node == target) return true;
}
para.addEventListener("mouseover", function(event) {
if (!isInside(event.relatedTarget, para))
para.style.color = "red";
});
para.addEventListener("mouseout", function(event) {
if (!isInside(event.relatedTarget, para))
para.style.color = "";
});
</script>
Функция isInside
перебирает всех предков узла, пока не доходит до верха документа (и тогда узел равен null
), или же не находит заданного ей родителя.
Должен добавить, что такой эффект достижим гораздо проще через псевдоселектор CSS под названием :hover
, как показано ниже. Но когда при наведении вам надо делать что-то более сложное, чем изменение стиля узла, придётся использовать трюк с событиями "mouseover"
и "mouseout"
.
<style>
p:hover { color: red }
</style>
<p>Наведите мышь на этот <strong>параграф </strong>.</p>
- Обработчики событий
- События и узлы DOM
- Объекты событий
- Распространение (propagation)
- Действия по умолчанию
- События от кнопок клавиатуры
- Кнопки мыши
- Движение мыши
- События прокрутки
- События, связанные с фокусом
- Событие загрузки
- График выполнения скрипта
- Установка таймеров
- Устранение помех (debouncing)
- Итог
- Упражнения
- 7.7. Изменение указателей мыши
- Можно ли избавиться от необходимости использовать двойной щелчок кнопкой мыши при открытии папки?
- Могу ли я изменить или отключить звуки, которые проигрываются при запуске Windows, щелчке кнопкой мыши на папке и т. д.?
- Как сделать указатель мыши цветным или изменить его форму?
- Почему указатель оптической мыши самопроизвольно двигается по экрану?
- Файлы без расширения, как правило, текстовые. Как сделать, чтобы при двойном щелчке кнопкой мыши они открывались в Блокн...
- Как сделать, чтобы меню Пуск не сворачивалось после щелчка кнопкой мыши?
- Как одним щелчком кнопки мыши закрыть несколько окон одновременно?
- Диски С: и D: невозможно открыть простым щелчком кнопки мыши. Появляется сообщение Не найден файл file.exe. Что делать?
- Почему во время просмотра сайтов в Internet Explorer при прокрутке колесиком мыши страницу как бы листает волнами, а не ...
- Настройка указателей мыши
- Перемещение и копирование ячеек с помощью кнопки мыши