События мыши: mouseover/out, mouseenter/leave

События мыши: mouseover/out, mouseenter/leave

Здравствуйте!  В этом уроке мы продолжим разбираться с  событиями мыши и рассмотрим события, которые  возникают при движении мыши mouseover, mouseenter.

Эти события  возбуждаются, когда пользователь двигает мышью или наводит мышь (mouseover), уводит (mouseout) от элемента на веб-странице.

События мыши mouseover, mouseout

События mouseover/mouseout

Событие mouseover инициируется, когда мышь появляется над элементом, а mouseout – когда соотвественно уходит из него.
mouseover mouseout

При этом вы можете узнать, с какого именно  элемента пришла (или на какой) мышь, используя  такое дополнительное свойство объекта события как  relatedTarget.

Например, в обработчике события mouseover:

  • event.target –  это элемент, на который пришла мышь, то есть на котором собственно и  возникло событие.
  • event.relatedTarget – элемент, с которого пришла мышь.

А вот для mouseout всё будет  наоборот:

  • event.target – элемент, с которого ушла мышь, то есть на котором и возникло событие.
  • event.relatedTarget – элемент, на который  потом перешла мышь.

Пример:

  <div class="div">
 </div>
 <script>
  let div = document.querySelector("div.div");
  div.style.width="200px";
  div.style.height="200px";
  div.style.backgroundColor="red";
  div.addEventListener("mouseover", function () {
     this.style.backgroundColor="blue"; 
});
div.addEventListener("mouseout", function () {
     this.style.backgroundColor="red"; 
});
</script>

Просмотреть  пример

relatedTarget может быть null

Свойство relatedTarget может содержать null.

В принципе это вполне нормально и  будет означать, что мышь пришла не с элемента, а из-за пределов окна (или ушла за окно). Вы обязательно должны иметь в виду такую особенность, когда пишете код, который  и обращается к свойствам event.relatedTarget.

Частота событий

Событие mousemove срабатывает при передвижении мыши. Но это вовсе не значит, что каждый пиксель экрана порождает отдельное событие!

События mousemove и mouseover/mouseout  будут срабатывать так часто, насколько это будет позволять внутренняя система взаимодействия с мышью браузера.

Из этого можно сделать вывод, что если посетитель  будет двигать мышью быстро, то  соответственно элементы веб-страницы, через которые мышь  и проходит на большой скорости, могут быть пропущены.

Читайте также  Делегирование событий в JavaScript

На практике это  бывает полезно, потому что  вот таких промежуточных элементов может быть много, и если обрабатывать наведение и отведение с каждого, будут дополнительные  затраты.

С другой стороны, вы должны это  четко понимать  и не рассчитывать на то, что мышь  будет аккуратно проходить с одного элемента на другой и так далее. Нет, она  естественно «прыгает».

В частности, возможна такая  ситуация, когда курсор наводится в середину страницы, и при этом соответственно  relatedTarget=null,  потому что он, курсор, пришел из другого окна.

Важно иметь в виду эту особенность событий, чтобы не написать код, который рассчитан на последовательный проход над элементами. В остальном это вполне удобно.

 

События mouseenter и mouseleave

События mouseenter/mouseleave очень похожи на mouseover/mouseout. Они тоже срабатывают, когда курсор заходит на элемент и уходит с него, но с 2 отличиями.

  1. Не будут  учитываются переходы внутри элемента.
  2. События mouseenter/mouseleave не всплывают. (О всплытии я писал здесь).

Эти события более интуитивно понятны.

Когда курсор заходит на элемент – срабатывает событие  mouseenter, а затем – неважно, куда он внутри него переходит, mouseleave  сработает, когда курсор будет за пределами элемента

Делегирование

События mouseenter/leave конечно же более наглядны и понятны, но они не всплывают к сожалению, а значит с ними нельзя использовать и  делегирование событий.

Например, что нам нужно обработать вход/выход мыши для ячеек таблицы. А в таблице  может быть таких ячеек тысяча.

Очевидное решение – это поставить обработчик на верхний элемент <table> и ловить все события на нём. Но события mouseenter/leave не всплывают, а следовательно они срабатывают именно на том элементе, на котором и  стоит обработчик и только на нём родимом.

Читайте также  Отмена действий браузера по умолчанию

Если обработчики mouseenter/leave стоят на <table>, то они конечно сработают при входе-выходе из таблицы, но  вот получить из них какую-либо информацию о переходах по  ячейкам будет  невозможно.

Но это нам не помеха – воспользуемся mouseover/mouseout.

Вот  вариант обработчиков выглядит так:

table.onmouseover = function(event) {
  var target = event.target;
  target.style.background = 'pink';
};

table.onmouseout = function(event) {
  var target = event.target;
  target.style.background = '';
};

В таком виде они  будут срабатывать при переходе с любого элемента на любой. Нас же будут  интересовать переходы с одной ячейки <td> на другую.

Нужно будет фильтровать события.

Один из вариантов:

  • Запоминать текущий подсвеченный <td> в переменной.
  • При mouseover проверять, остались ли вы внутри того же <td>, если да – то  игнорировать.
  • При mouseout проверять, если мы ушли с текущего <td>, а не перешли  внутрь него, то конечно игнорировать.

Итоги

У mouseover, mousemove, mouseout есть такие особенности:

  • При очень быстром движении мыши события mouseover, mousemove, mouseout могут пропускать элементы.
  • События mouseover и mouseout – единственные, у которых есть вторая цель: relatedTarget.
  • События mouseover/mouseout подразумевают, что курсор находится над одним, самым глубоким элементом. Они срабатывают при переходе с родительского элемента на дочерний.

События mouseenter/mouseleave не всплывают и не будут учитывать переходы внутри элемента.

Задачи

Поведение  еще одна подсказака

Вам требуется написать  JS-код, который будет показывать всплывающую подсказку над элементом, если у него имеется атрибут data-tooltip.

Подсказка при замедлении над элементом

Вам нужно написать функцию, которая  будет показывать подсказку при наведении на элемент, но не при быстром проходе над ним.

То есть, если пользователь навёл курсор мыши на элемент и почти остановился – подсказку  надо показать, а если быстро провёл над ним, то не надо.

Читайте также  Всплытие и перехват событий

Технически – можно измерять скорость движения мыши над элементом, если она маленькая, то считаем, что это «наведение на элемент» (показать подсказку), если большая – «быстрый проход мимо элемента» (не показывать).

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Плюсануть
Поделиться

Об авторе

admin administrator

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: