【问题标题】:How to get setTimeout to start counting as soon as the alert box is open一旦警报框打开,如何让 setTimeout 开始计数
【发布时间】:2015-10-19 02:42:21
【问题描述】:

我目前有一个函数使用setTimeout() 函数内的alert() 函数创建警报,并且嵌套在for 循环内。

所以它看起来像这样

for(i<10){
 setTimeout(function(param){
  alert(param);
 3000, param);
  i++
}

我这样做时遇到的问题是,计时器仅在我在警报框上单击“确定”后才开始计时。

所以弹出第一个警报,我点击确定,3 秒后出现第二个框。

相反,我希望能够出现第一个警报,等待 3 秒,按确定,然后立即出现第二个警报

我该怎么做?

编辑:我按照建议尝试了 setInterval 而不是 setTimeout ,但它似乎让我陷入了设定的间隔循环?

这是我的代码:

for (var product in cart) {
    alert(product);
    setTimeout(function(item) {
        alert("Name: " + item + ": Quantity: " + cart[item]);
    }, i * 3000, product);
    i++;
}

我刚刚尝试用 setInterval 替换 setTimeout,之后我也尝试了 clearInterval,但该框甚至没有出现

【问题讨论】:

  • 您应该使用setInterval 而不是您所做的。此外,您的 for 循环无效。如果有的话,它应该是一个while循环......
  • 项目在哪里定义?
  • 还有为什么setTimeout里面有三个参数?
  • setTimeout 的第三个参数我相信应该是函数的参数,所以 item = product

标签: javascript jquery alert settimeout


【解决方案1】:

您需要使用 setInterval() 来执行代码以一定的时间间隔。使用 clearInterval() 取消 setInterval() 操作。

var i = 0,
  param = 'hi';
var intr = setInterval(function(param) {
  if (++i === 10)
    clearInterval(intr);
  console.log(param);
}, 3000, param);

在您的情况下,您可以使用 Object.keys() 将对象键放入数组中,然后在 setInterval() 中使用索引来获取它。

var i = 0,
  cart = {
    car: 1,
    car1: 2,
    car2: 3,
    car3: 4,
    car4: 5,
    car5: 6,
    car6: 7,
    car7: 8,
    car8: 9,
    car9: 10
  },
  // getting object keys
  arr = Object.keys(cart);
// initializing interval
var intr = setInterval(function(p) {
  // getting value using key
  alert('Name : ' + p[i] + ' Quantity : ' + cart[p[i]]);
  // canceling interval
  if (++i === 10)
    clearInterval(intr);
}, 3000, arr);

【讨论】:

  • 我找到了使用 Object.keys 的更好方法
  • 赞成,因为您使用了键控。它可以防止需要阻止的 for 循环继续。
【解决方案2】:

for 循环将尽可能快地执行,因此您的超时只会在t~=0 + timeout 处调用,这不会引起注意。

您需要增加一个变量并将超时设置为variable*timeout

另外,对window.alert 的调用会停止脚本的执行。您可能需要使用其他方式来显示您的信息框(如模式窗口):

var obj = {x:1, y:2, z:3}
var i = 0;
var now = performance.now();
for(var p in obj){
  setTimeout(function(){snippet.log(this +' __ '+  (performance.now()-now));}.bind(obj[p]), ++i*3000);
  }
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

【讨论】:

  • 这是我最初正在做的事情,但是当这样做时,计时器在我关闭第一个警报框之前不会启动,我希望计时器在第一个警报框出现后立即启动
  • 这是因为window.alert() 停止了 javascript 的执行。使用警报以外的东西(即模式窗口)来避免它。
【解决方案3】:

更新为在迭代产品属性时工作: 我通过保留一个 setInterval 并使用 Object.keys(obj) 获取对象属性使其变得简单

var products = {
    sexdoll: '$69',
    dog: '$0',
    soul: '$minimum wage'
}, keyedProducts = Object.keys(products);

var i=0, intval = setInterval(function() {
    alert(keyedProducts[i]);
    if(++i > keyedProducts.length-1) { clearInterval(intval) }
}, 3000);

http://jsfiddle.net/xybt1g9x/

【讨论】:

  • 不幸的是,我必须使用 for 循环,因为我正在使用 for(var product in cart)
  • @StevenHsu 将其更新为尽可能短。它会每 3 秒吐出你产品中的每个属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 2015-06-09
  • 2019-02-03
  • 2013-10-10
  • 1970-01-01
相关资源
最近更新 更多