在mousemove之后无限循环

时间:2017-10-19 16:30:26

标签: javascript while-loop infinite-loop

我在这里疯了。 我想在鼠标移动时显示一个元素,并在鼠标最后一次移动后隐藏它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永远不会得到'真正的'参数? 注意:不要以这种方式运行它......它会杀死你的标签。

3 个答案:

答案 0 :(得分:2)

首先,您无需等待DOMContentLoadeddocument添加事件监听器,因为如果您这样做,则无法首先添加DOMContentLoaded

无限循环是因为setTimeout不会暂停脚本。它会根据您提供的时间安排其回调,并且无论何时,回调都不会运行,直到线程中当前运行的代码完成,这从未发生,因为您没有增加{{ 1}}变量。

因此循环永远不会结束,因此线程永远不可用,因此您的回调永远不会运行,因此time永远不会递增。

最后,在共享局部变量的事件处理程序中启动time并在setTimeout之类的事件上执行非常快,很容易产生意外结果。例如,在您的代码中,每次处理程序运行时,它都会将mousemove重置为time,这似乎不是您想要的。

解决方案是抛弃循环,安排可见性10秒,并通过使用布尔变量防止处理程序中代码的主要部分同时运行。

0

我也改为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因为它更短更清洁。我在设置样式之前使用了一个变量来确保找到元素。

答案 1 :(得分:0)

你需要一个不在mousemove范围内的标志,告诉你的听众你已经跑了。

Users/uid/PurchasedItems/itemid

    // Existing 
    payedInMoney: "$0.00"
    payedInCoins: "100"
    itemId: "itemid"
    timeStamp: timestamp

    // Add these
    name: "Item Name"
    url: "http://foo.bar/123"

在上下文中:

if(running) return; 
running = true;

答案 2 :(得分:0)

这是使用常规JavaScript执行此操作的方法。如果您的浏览器不符合ES6,则可以使用常规函数表达式替换箭头函数。该示例在2秒而不是10秒后隐藏文本,这样您就可以看到它的工作而不必浪费8秒钟。

&#13;
&#13;
//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();
});
&#13;
<body>
  <div id='myBar'>
    <h1> TESTING </h1>
  </div>
</body>
&#13;
&#13;
&#13;