2017-10-19 2 views
0

Ich werde hier verrückt. Ich möchte ein Element beim Bewegen der Maus anzeigen und es 10 Sekunden nach dem letzten Mausklick ausblenden. IchEndlosschleife nach Mausbewegung

schrieb dies:

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> 

Warum ist es in einer Endlosschleife enden? Warum verlässt es nicht unter Bedingung? Warum erhält der if niemals den 'wahren' Parameter? Hinweis: Führen Sie es nicht auf diese Weise ... es wird Ihren Tab töten.

+0

Was hier ist Ihr Ziel? Versuchen Sie einfach, das div für 10 Sekunden zu zeigen, wenn sich die Maus innerhalb des Fensters bewegt? – Turk

+0

Sie brauchen das 'while' nicht. 'setTimeout' erledigt das ganze Timing für Sie.Sie müssen nur sagen, was nach 'n' Millisekunden aufgerufen werden soll. – zero298

+3

weil setTimeout asynchron ist. – epascarello

Antwort

2

Zunächst müssen Sie nicht auf DOMContentLoaded warten, um einen Ereignis-Listener zu document hinzuzufügen, da Sie DOMContentLoaded an erster Stelle nicht hinzufügen konnten.

Die Endlosschleife ist, weil setTimeout das Skript nicht pausiert. Es plant seinen Rückruf für die Zeit, die Sie bereitstellen, und unabhängig von dieser Zeit werden die Callbacks nicht ausgeführt, bis der aktuelle Ausführungscode im Thread abgeschlossen ist, was nie geschieht, weil Sie die Variable time nicht inkrementieren.

So endet die Schleife nie, und so wird der Thread nie zur Verfügung gestellt, so dass Ihre Rückrufe nie ausgeführt werden können, so time kann nie inkrementiert werden.

Schließlich startet ein setTimeout in einem Ereignishandler, der eine lokale Variable teilt und sehr schnell auf einem Ereignis wie mousemove ausgeführt wird, zu unerwarteten Ergebnissen führen. Zum Beispiel wird in Ihrem Code jedes Mal, wenn der Handler ausgeführt wird, time auf 0 zurückgesetzt. Dies scheint nicht das zu sein, was Sie möchten.


Eine Lösung wäre es, die Schleife zu Graben, plant die Sichtbarkeit für 10 Sekunden und den Hauptteil des Codes in dem Handler vom Laufen in der Zwischenzeit zu verhindern, indem eine Boolsche Variable verwendet wird.

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); 
}); 

Ich wechselte auch querySelector statt getElementsByClassName, weil es kürzer und sauberer ist. Und ich habe eine Variable verwendet, um sicherzustellen, dass das Element gefunden wird, bevor der Stil festgelegt wird.

+0

Danke. Es ist sehr ähnlich zu dem, was ich am Anfang geschrieben habe. Und es hat funktioniert, wie Sie es tun. Das einzige Problem auf diese Weise ist, dass 10 Sekunden nach dem ersten Zug der Balken verschwindet ... auch wenn sich die Maus danach bewegt hat. – matisa

+1

@matisa: Wenn Sie möchten, dass es 10 Sekunden nach der * letzten * Mausbewegung verschwindet, müssen Sie * das Timeout löschen * und jedes Mal ein neues Ereignis starten, wenn ein solches Ereignis eintritt. Ich werde das Beispiel aktualisieren. – llama

0

Sie benötigen ein Flag aus dem Mousemove-Bereich, das Ihrem Listener sagt, dass Sie bereits ausgeführt haben.

if(running) return; 
running = true; 

Im Kontext:

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

Aber in diesem Fall wird es nur einmal ausgeführt. Es baut einen Spieler. Ich brauche ich möchte die Steuerleiste 10 Sekunden nach der Bewegung der Maus verschwinden verschwinden. Auf neue Bewegung muss ich es wieder erscheinen lassen. – matisa

0

Hier ist ein Weg, um es mit regelmäßigen JavaScript zu tun. Wenn Ihr Browser nicht mit ES6 kompatibel ist, können Sie die Pfeilfunktionen durch normale Funktionsausdrücke ersetzen. Im Beispiel wird der Text nach 2 statt 10 Sekunden ausgeblendet, damit Sie sehen können, dass er funktioniert, ohne 8 zusätzliche Sekunden verschwenden zu müssen.

//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>