2017-10-19 136 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>