GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Учебник
  • Курсы
  • Форум
  • Тесты знаний
  • Node.js
  • Webpack
  • Gulp
  • React.js
  • Angular
  • Git: курс
  • Git: разное

This view

  • Original page
  • New address

GeezerVison is showing learn.javascript.ru — "Умная" подсказка

  • Учебник
  • Браузер: документ, события, интерфейсы
  • Интерфейсные события
  • Движение мыши: mouseover/out, mouseenter/leave
вернуться к уроку

"Умная" подсказка

важность: 5

Напишите функцию, которая показывает подсказку над элементом только в случае, когда пользователь передвигает мышь на него, но не через него.

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

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

Создайте для этого универсальный объект new HoverIntent(options).

Его настройки options:

  • elem – отслеживаемый элемент.
  • over – функция, вызываемая, при заходе на элемент, считаем что заход – это когда курсор медленно двигается или остановился над элементом.
  • out – функция, вызываемая при уходе курсора с элемента (если был заход).

Пример использования такого объекта для показа подсказки:

// пример подсказки
let tooltip = document.createElement('div');
tooltip.className = "tooltip";
tooltip.innerHTML = "Tooltip";

// объект будет отслеживать движение мыши и вызывать функции over/out
new HoverIntent({
  elem,
  over() {
    tooltip.style.left = elem.getBoundingClientRect().left + 'px';
    tooltip.style.top = elem.getBoundingClientRect().bottom + 5 + 'px';
    document.body.append(tooltip);
  },
  out() {
    tooltip.remove();
  }
});

Демо:

Если двигать курсор над «часами» быстро, то ничего не произойдёт, а если вы замедлите движение курсора над элементом или остановите его, то будет показана подсказка.

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

Открыть песочницу с тестами для задачи.

Алгоритм выглядит просто:

  1. Назначаем обработчики onmouseover/out на элементе. Также можно было бы использовать onmouseenter/leave, но они менее универсальны и не сработают с делегированием.
  2. Когда курсор переходит на элемент, начинаем измерять скорость его движения, используя mousemove.
  3. Если скорость низкая, то вызываем over.
  4. Когда мы выходим из элемента, если запускали over, вызываем out.

Но как измерить скорость?

Первая идея может быть такой: запускать нашу функцию каждые 100ms и находить разницу между прежними и текущими координатами курсора. Если она мала, то значит и скорость низкая.

К сожалению, в JavaScript нет возможности получать текущие координаты мыши. Не существует функции типа получитьТекущиеКоординатыМыши().

Единственный путь – это слушать события мыши, например mousemove, и координаты брать из объекта события.

Так что поставим обработчик на mousemove, чтобы отслеживать координаты и запоминать их. И будем сравнивать результаты каждые 100ms.

P.S. Обратите внимание: тесты для решения этой задачи используют dispatchEvent, чтобы проверить, что подсказка работает корректно.

Открыть решение с тестами в песочнице.

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.