首页 > 解决方案 > DOM - 同时事件的时间与 setTimeout

问题描述

假设我有一个包含多个子元素的元素,并且想要在鼠标进入或离开容器时运行一些代码。如果我天真地写:

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

标签: javascriptdomlanguage-lawyerdom-eventsevent-loop

解决方案


使用mouseenterandmouseleave事件而不是mouseoverand mouseout


推荐阅读