Представьте, что у меня есть следующие элементы:
+------------------+
| |
| +----------------+
| | |
| | |
| +----------------+
| |
+------------------+
Внутренний элемент имеет позиционирование, что означает, что он может визуально находиться вне своего родителя, и я помещаю слушателя событий в родительский элемент, например:
parent.addEventListener('mouseover', function(e) {
// log mouse is over me
}, false);
Если я наведу указатель мыши непосредственно на родителя снизу, я получу прямое событие, но из-за маршрутизации событий, если я наведу указатель мыши сбоку (сначала ударив ребенка), я также получу событие от дочернего элемента, когда оно всплывает. .
Если я продолжу идти влево, пока не выйду из дочернего элемента и не окажусь в родительском пространстве, я получу прямое событие, если я снова пойду вправо, я получу еще одно всплывающее событие от дочернего элемента.
Это сделано по дизайну, и дизайн абсолютно хорош, однако, если я хочу выполнить ОДНО действие, когда указатель мыши наведен на меня (включая мои дочерние элементы), мне нужно проделать дополнительную работу, чтобы заблокировать события, которые меня не интересуют. . например, это будет работать:
var isOver = false;
parent.addEventListener('mouseover', function(e) {
if (isOver) return;
isOver = true;
// log mouse is over me
}, false);
parent.addEventListener('mouseout', function(e) {
if (e.relatedTarget == this || e.relatedTarget.isDescendantOf(this)) return;
isOver = false;
// log mouse is leaving me
}, false);
По сути, в коде есть переменная состояния, чтобы определить, «перекрыла» ли мышь родительский элемент (либо через своего дочернего элемента, либо нет), и если событие срабатывает снова, пока «перекрывает» эти события, эти события игнорируются ... мы также фиксируем событие выхода мыши и спросите его .. является ли relatedTarget (цель, которую вы собираетесь ввести) Я? (родитель) или возможный ребенок МЕНЯ? если это так, то ничего не делайте ... в противном случае установите для состояния "перекрытие" значение false.
Итак, этот код действительно работает, но представьте, что я не могу использовать свойство relatedTarget для определения следующей цели, как бы вы поступили с таким поведением?
Я надеюсь, что это имеет смысл, я чувствую, что в событиях недостаточно контекста, чтобы делать это без relatedTarget, но я чувствовал, что вполне может быть угол в отношении изменения поведения свойства eventPhase (чтобы определить, является ли событие прямым или пузырьковым).
Также я не ищу ответов, в которых говорится: «Это не будет работать в IE, yadda yadda» .. Я работаю только против браузеров спецификации событий w3c прямо сейчас.
Отредактируйте, просто чтобы уточнить, я хочу, чтобы события происходили так, как если бы у меня был один элемент, который выглядел бы так (если бы элемент действительно был таким, как в примере выше):
+------------------+
| |
| +--+
| |
| |
| +--+
| |
+------------------+