如何在循环中执行事件直到事件为真

How to execute an event in a loop until the event is true

当事件侦听器正在运行时,我陷入 Javascript 循环一段代码 放置.

例如,假设我有一个 div:

<div id="option">
</div>

并且我添加了一个 Javascript mouseenter 事件侦听器:

const divItem = document.getElementById("option")
divItem.addEventListner("mouseenter", () => {
    console.log("Mouse is entered")
})

现在控制台日志只在我悬停鼠标后出现一次,但我希望它每隔 4 秒出现一次 并在控制台中记录相同的消息,直到鼠标移出 div.

我尝试使用 setTimeout:

divItem.addEventListner("mouseenter", () => {
    const timeoutEvent = () => {
         console.log("Mouse is entered")
         setTimeout( () => { timeoutEvent() }, 4000 )
    }
    timeoutEvent()
})

但即使在鼠标离开 div 后它仍在记录, 那我该如何解决呢?

你走在正确的轨道上。如果你想要每四秒一次,你想要:

  • 使用setInterval(或者每次都设置一个新的setTimeout),并且
  • 看到mouseleave就取消

const divItem = document.getElementById("option")
// The timer handle so we can cancel it
let timer = 0; // A real timer handle is never 0, so we can use it as a flag
divItem.addEventListener("mouseenter", () => {
    console.log("Mouse is entered");
    timer = setInterval(() => {
        if (timer) {
            console.log("Mouse is still here");
        }
    }, 1000);
})
divItem.addEventListener("mouseleave", () => {
    console.log("Mouse left");
    clearInterval(timer);
    timer = 0;
});
<div id="option">
this is the div
</div>

(我在该示例中使用了一秒钟而不是四秒钟,因此更容易看到它的工作。)

或使用 setTimeout 重新安排自身:

const divItem = document.getElementById("option")
// The timer handle so we can cancel it
let timer = 0; // A real timer handle is never 0, so we can use it as a flag
const timerInterval = 1000;
function tick() {
    if (timer) {
        console.log("Mouse is still here");
        timer = setTimeout(tick, timerInterval);
    }
}
divItem.addEventListener("mouseenter", () => {
    console.log("Mouse is entered");
    timer = setTimeout(tick, timerInterval);
})
divItem.addEventListener("mouseleave", () => {
    console.log("Mouse left");
    clearTimeout(timer);
    timer = 0;
});
<div id="option">
this is the div
</div>

您应该使用 setInterval 而不是 setTimeout

您可以在全局范围内定义 'interval' 函数和间隔,然后使用它们来设置和启动 mouseenter/mouseleave 事件的间隔执行和 clearInterval(停止执行)。

const divItem = document.getElementById("option")
let myInterval;
const timeoutEvent = () => {
  console.log("Mouse is entered")
}
divItem.addEventListener("mouseenter", () => {
  myInterval = setInterval(timeoutEvent, 1000);
})
divItem.addEventListener("mouseleave", () => clearInterval(myInterval))
<div id="option">
  My Option
</div>

divItem.addEventListener("mouseenter", () => {
    console.log("Mouse is entered");
    timer = setInterval(() => {
            console.log("Mouse is still here");
        }
    }, 4000);
})