javascript - document.hidden 时暂停/恢复 setInterval

标签 javascript

我需要每 30 秒显示一次警报。如果用户临时切换到其他选项卡,计时器必须卡住。

我的代码如下:

var alertIntervalId = null
var quotes = ['quote1', 'quote2', 'quote3']
var NOTIFICATION_INTERVAL = 5
var TIMEOUT_IN_SECS = 5

var alertInterval = setInterval(function() {
    setTimeout(function() {
        randomIdx = Math.floor(Math.random() * quotes.length)
        alert(quotes[randomIdx])
    }, NOTIFICATION_INTERVAL * 1000)
}, TIMEOUT_IN_SECS * 1000)

function handleVisibilityChange(){
    if (document.hidden) {
        clearInterval(alertIntervalId)
        alertIntervalId = null
    } else {
      alertIntervalId = alertIntervalId || alertInterval()
    }
}

document.addEventListener("visibilitychange", handleVisibilityChange, false);
handleVisibilityChange()

但是代码不起作用(没有发生卡住),我不明白为什么。

附注我刚刚开始学习 JavaScript,所以请考虑不要扔烂番茄。

编辑:

稍微重构后,代码如下所示

var alertIntervalId = null
var quotes = ['quote1', 'quote2', 'quote3']
var NOTIFICATION_INTERVAL = 5
var TIMEOUT_IN_SECS = 5

var alertInterval = function() {
  return setInterval(function() {
    setTimeout(function() {
      var randomIdx = Math.floor(Math.random() * quotes.length);
      alert(quotes[randomIdx])
    }, NOTIFICATION_INTERVAL * 1000)
  }, TIMEOUT_IN_SECS * 1000)
}

function handleVisibilityChange(){
    if (document.hidden) {
        clearInterval(alertIntervalId)
        alertIntervalId = null
    } else {
      alertIntervalId = alertIntervalId || alertInterval()
    }
}

document.addEventListener("visibilitychange", handleVisibilityChange, false);
handleVisibilityChange()

但是切换到其他选项卡后警报仍然没有被卡住:(

最佳答案

使用https://developer.mozilla.org/en-US/docs/Web/Events/visibilitychange检测用户何时单击不同的选项卡,并在文档隐藏时卡住间隔,或者在文档可见时再次激活它。

正如所写,您永远不会知道文档何时隐藏,因为它仅在您运行handleVisibilityChange() 函数时检查隐藏属性。

所以我更喜欢使用事件监听器和单个 setInterval。

编辑:

问题是您的代码中有错误。打开控制台可以看到alertInterval不是一个函数。由于您使用 var alertInterval = setInterval(function() {}alertInterval 实际上是间隔的 id,而不是返回间隔的函数。所以将其更改为:

var alertInterval = function() {
  return setInterval(function() {
    setTimeout(function() {
        randomIdx = Math.floor(Math.random() * quotes.length)
        alert(quotes[randomIdx])
    }, NOTIFICATION_INTERVAL * 1000)
  }, TIMEOUT_IN_SECS * 1000);
};

这样它仍然是一个返回新间隔 ID 的函数。

我仍然不明白为什么你同时使用 setInterval() 和 setTimeout(),但这可能超出了问题范围。

编辑2:

我一直在测试这段代码,它在 IE11 和 chrome 中的这段代码中适用于我。

所以看看你的随机报价等等。

var alertIntervalId = null;
var quotes = ['quote1', 'quote2', 'quote3'];
var NOTIFICATION_INTERVAL = 5;
var TIMEOUT_IN_SECS = 5;

var alertInterval = function() {
  return setInterval(function() {
    setTimeout(function() {
      var randomIdx = Math.floor(Math.random() * quotes.length);
      console.log(quotes[randomIdx]);
    }, NOTIFICATION_INTERVAL * 1000);
  }, TIMEOUT_IN_SECS * 1000);
};

function handleVisibilityChange(){
  if (document.hidden) {
    console.log( 'tab became hidden, clearing' );
    clearInterval(alertIntervalId)
    alertIntervalId = null;
  } else {
    console.log( 'tab became visible, restarting' );
    alertIntervalId = alertIntervalId || alertInterval();
  }
}

document.addEventListener("visibilitychange", handleVisibilityChange, false);
handleVisibilityChange();

关于javascript - document.hidden 时暂停/恢复 setInterval,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54128923/

相关文章:

javascript - 从 JSON 填充 Google map 标记

javascript - 如何在 Fabric.js 中为文本添加 CSS 属性

javascript - Angular 仅发送模型的更改字段或复制更改后的模型

javascript - Jquery .css() 不起作用(可能是由其他原因引起的)

javascript - Amazon S3 CORS 仍然无法工作 : No 'Access-Control-Allow-Origin'

javascript - 延迟加载外部 Javascript 文件

javascript - 在一次数组迭代中按名称从数组中获取对象

javascript - 如何克隆实际的 iFrame 内容,而不仅仅是 iFrame 标签内容?

javascript - 如何过滤表格?

javascript - 使用 JQuery 使一张卡片在打开另一张卡片后关闭