2017-10-19 137 views
0

我要瘋了。 我想在鼠標移動中顯示一個元素,並在最後一次移動鼠標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'參數? 注意事項:不要這樣運行......它會殺死你的標籤。

+0

是什麼在這裏你的目標?當鼠標在窗口內移動時,你只是試圖顯示div 10秒鐘? – Turk

+0

你不需要'while'。 'setTimeout'爲你完成所有的時間。你只需要告訴它在'n'毫秒後要調用什麼。 – zero298

+3

,因爲setTimeout是異步的。 – epascarello

回答

2

首先,您不需要等待DOMContentLoaded將事件偵聽器添加到document,因爲如果您這樣做了,則無法在第一位添加DOMContentLoaded

無限循環是因爲setTimeout不會暫停腳本。它會根據您提供的時間安排回調,並且不管時間如何,回調將不會運行,直到線程中的當前運行代碼完成爲止,這種情況從未發生,因爲您不會增加time變量。

所以循環不會結束,所以線程永遠不可用,所以你的回調永遠不會運行,所以time永遠不會增加。

最後,在事件處理程序中啓動一個setTimeout,該事件處理程序共享一個局部變量,並在像mousemove這樣的事件上執行得非常迅速,這很容易導致意外的結果。例如,在您的代碼中,每次處理程序運行時,都會將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,因爲它是更短和更清潔。在設置樣式之前,我使用了一個變量來確保元素被找到。

+0

謝謝。這和我一開始寫的非常相似。 它的工作,因爲你的代碼。這種方式唯一的問題是,第一次移動10秒後,酒吧將消失...即使鼠標移動後。 – matisa

+1

@matisa:那麼如果你希望它在* last * mousemove後10秒消失,你需要做的是*清除*超時並在每次發生這樣的事件時開始一個新的。我會更新這個例子。 – llama

0

你需要一個鼠標移動範圍的標誌,告訴你的聽衆你已經跑了。

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'; 
     } 
    } 
    }); 
}); 
+0

但在這種情況下,它只會運行一次。 它正在建立一個球員。 我需要我希望控制條在鼠標停止移動10秒後消失。在新的運動中,我需要它再次出現。 – matisa

0

這裏有一個方法與常規的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>