Подсказка при замедлении над элементом
Нужно написать функцию, которая показывает подсказку при наведении на элемент, но не при быстром проходе над ним.
То есть, если посетитель именно навёл курсор мыши на элемент и почти остановился – подсказку показать, а если быстро провёл над ним, то не надо, зачем излишнее мигание?
Технически – можно измерять скорость движения мыши над элементом, если она маленькая, то считаем, что это «наведение на элемент» (показать подсказку), если большая – «быстрый проход мимо элемента» (не показывать).
Реализуйте это через универсальный объект new HoverIntent(options)
, с параметрами options
:
elem
– элемент, наведение на который нужно отслеживать.over
– функция-обработчик наведения на элемент.out
– функция-обработчик ухода с элемента (если было наведение).
Пример использования такого объекта для подсказки:
// образец подсказки
var tooltip = document.createElement('div');
tooltip.className = "tooltip";
tooltip.innerHTML = "Подсказка";
// при "наведении на элемент" показать подсказку
new HoverIntent({
elem: elem,
over: function() {
tooltip.style.left = this.getBoundingClientRect().left + 'px';
tooltip.style.top = this.getBoundingClientRect().bottom + 5 + 'px';
document.body.appendChild(tooltip);
},
out: function() {
document.body.removeChild(tooltip);
}
});
Демо этого кода:
Если провести мышкой над «часиками» быстро, то ничего не будет, а если медленно или остановиться на них, то появится подсказка.
Обратите внимание – подсказка не «мигает» при проходе мыши внутри «часиков», по подэлементам.
Открыть песочницу с тестами для задачи.
Будем замерять скорость движения курсора.
Для этого можно запустить setInterval
, который каждые 100 мс (или другой интервал) будет сравнивать текущие координаты курсора с предыдущими и, если расстояние пройдено маленькое, считаем, что посетитель «навёл указатель на элемент», вызвать options.over
.
В браузере нет способа «просто получить» текущие координаты. Это может сделать обработчик события, в данном случае mousemove
. Поэтому нужно будет поставить обработчик на mousemove
и при каждом движении запоминать текущие координаты, чтобы setInterval
мог раз в 100 мс сравнивать их.
Имеет смысл начинать анализ координат и отслеживание mousemove
при заходе на элемент, а заканчивать – при выходе с него.
Чтобы точно отловить момент входа и выхода, без учёта подэлементов (во избежание мигания), можно использовать mouseenter/mouseleave
.
В решении, предложенном ниже, однако, используется mouseover/mouseout
, так как это позволит легко «прикрутить» к такому объекту делегирование, если потребуется. А, чтобы не было лишних срабатываний, лишние переходы отфильтровываются.
При этом при обнаружении «наведения на элемент» это запоминается в переменной isHover
и вызывается options.over
, а затем, при выходе с элемента, если было «наведение», вызывается options.out
.