Предположим, у меня есть элемент, содержащий несколько дочерних элементов, и я хочу запустить некоторый код всякий раз, когда мышь входит в контейнер или покидает его. Если я наивно напишу:
var onHover = function (el, f) {
el.addEventListener('mouseover', function () {
f(true);
});
el.addEventListener('mouseout', function () {
f(false);
});
};
Тогда я получаю желаемое поведение в некоторых случаях - в зависимости от характера обратного вызова f
. Однако, когда мышь перемещается от дочернего элемента к дочернему в пределах контейнера, сразу запускается f(false)
, а затем f(true)
. Я не хочу, чтобы это произошло - я хочу, чтобы f
запускался только тогда, когда мышь входит в контейнер или покидает его целиком, а не в стиле «пулемет», поскольку пользователь перетаскивает мышь над элементами, которые находятся внутри контейнера. .
Вот решение, которое я придумал:
var onHover = function (el, f) {
var previousMouseover = false;
var receivedMouseover = false;
var pushing = false;
var pushEv = function () {
if (pushing) { return; }
pushing = true;
setTimeout(function () {
pushing = false;
if (previousMouseover !== receivedMouseover) {
f(receivedMouseover);
previousMouseover = receivedMouseover;
}
});
};
el.addEventListener('mouseover', function () {
receivedMouseover = true;
pushEv();
});
el.addEventListener('mouseout', function () {
receivedMouseover = false;
pushEv();
});
};
Это решение, как и первое решение, предполагает и работает благодаря тому, что событие mouseout
отправляется до события mouseover
. Я также хотел бы знать, формально ли , что указано в какой-либо документации W3C, но это не тема этого вопроса, и даже если бы это было не так, было бы легко написать работающий алгоритм несмотря на это, установив две отдельные переменные, скажем receivedMouseover
и receivedMouseout
внутри обратных вызовов mouseover
и mouseout
, оба из которых затем проверяются внутри обратного вызова setTimeout
.
Вопрос заключается в следующем: требуется ли, чтобы оба события mouseover
и mouseout
были обработаны до любых setTimeout
обратных вызовов, зарегистрированных любым из этих событий?