[英]endless while loop after mousemove
我在這里瘋了。 我想在鼠標移動時顯示一個元素,並在鼠標最后一次移動10秒后將其隱藏。
我這樣寫:
document.addEventListener("DOMContentLoaded", function(event) {
var time = 0;
document.addEventListener("mousemove", function(event) {
console.log('$');
document.getElementsByClassName("mybar")[0].style.visibility = 'visible';
time = 0;
while (time < 11) {
setTimeout(function() {
time++
}, 1000);
console.log(time, time == 10);
if (time == 10) {
document.getElementsByClassName("mybar")[0].style.visibility = 'hidden';
}
}
});
});
<div class='mybar'>
<h1> TESTING </h1>
</div>
為什么會陷入無休止的循環? 為什么不按條件退出? 為什么if永遠不會獲得'true'參數? 注意 :請勿以這種方式運行它...它將殺死您的標簽頁。
首先,您無需等待DOMContentLoaded
將事件偵聽器添加到document
,因為如果您這樣做了,則首先就不能添加DOMContentLoaded
。
無限循環是因為setTimeout
不會暫停腳本。 它為您提供的時間安排回調,無論該時間如何,回調都不會運行,直到線程中當前正在運行的代碼完成為止,這永遠不會發生,因為您不會增加time
變量。
因此循環永遠不會結束,因此線程永遠不會可用,因此回調永遠無法運行,因此time
永遠不會增加。
最后,在共享局部變量並在諸如mousemove
類的事件上非常快速地執行的事件處理程序中啟動setTimeout
容易產生意外結果。 例如,在您的代碼中,每次處理程序運行時,它都會將time
重置為0
,這似乎並不是您想要的。
一種解決方案是放棄循環,安排可見性10秒鍾,並使用布爾變量防止處理程序中代碼的主要部分同時運行。
var timer = null;
document.addEventListener("mousemove", function(event) {
var myBar = document.querySelector(".mybar");
if (!myBar) {
return; // there's no mybar element
}
if (timer == null) {
myBar.style.visibility = 'visible';
} else {
clearTimeout(timer); // clear the currently running timer
}
// set to hidden in 10 seconds
timer = setTimeout(function() {
myBar.style.visibility = 'hidden';
timer = null; // clear the timer
}, 10000);
});
我還切換到了querySelector
而不是getElementsByClassName
因為它更短,更干凈。 而且我使用了一個變量來確保在設置樣式之前找到了元素。
您需要在mousemove范圍之外標記一個標志,該標志告訴偵聽器您已經運行了。
if(running) return;
running = true;
在上下文中:
document.addEventListener("DOMContentLoaded", function(event) {
var time = 0;
var running = false;
document.addEventListener("mousemove", function(event) {
console.log('$');
if(running) return;
running = true;
document.getElementsByClassName("mybar")[0].style.visibility = 'visible';
time = 0;
while (time < 11) {
setTimeout(function() {
time++
}, 1000);
console.log(time, time == 10);
if (time == 10) {
document.getElementsByClassName("mybar")[0].style.visibility = 'hidden';
}
}
});
});
這是使用常規JavaScript的一種方法。 如果您的瀏覽器不符合ES6,則可以用正則函數表達式替換箭頭函數。 該示例在2秒而不是10秒后隱藏了文本,只是為了您可以看到它起作用而不必浪費8秒。
//hide by default document.getElementById('myBar').style.display = 'none'; var timer = null; var hideDivTimer = () => { timer = setTimeout(() => { document.getElementById('myBar').style.display = 'none'; }, 2000); }; document.addEventListener('mousemove', () => { clearTimeout(timer); document.getElementById('myBar').style.display = 'inline'; hideDivTimer(); });
<body> <div id='myBar'> <h1> TESTING </h1> </div> </body>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.