以下代码将输出显示为
应首先调用>>假
隐藏..停止运行昂贵的任务
它似乎第一次按顺序运行以进一步重新加载页面,它以某种方式缓存eventlistener我猜...并给出以下输出。
隐藏..停止运行昂贵的任务
应首先调用>>假
console.warn("should have been called first >> "+ document.hidden);
/* event handlers */
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
console.log("hidden.. stop running expensive task")
} else {
console.log("not hidden.. page has focus, begin running task")
}
});
2个问题:
document.hidden
是假的?我无法找到有关此行为的更多信息。
<!DOCTYPE html>
<html>
<script>
console.warn("should have been called first >> "+document.hidden);
/* event handlers */
document.addEventListener('visibilitychange', function () {
if (document.hidden) {
console.log("hidden.. stop running expensive task")
} else {
console.log("not hidden.. page has focus, begin running task")
}
});
</script>
<body>
<p>
Just create a html page with this code.
Open browser console. You'll see the console statements in sequesnce.
Now if you reload this html page, the statements are out of sequence.
Somehow event callback is called first before console statement "should have been called first"</p>
</body>
</html>
只需使用上面的代码段创建一个html页面即可。 打开浏览器控制台您将看到控制台语句的连续性。 现在,如果你重新加载这个html页面,那么这些语句是不按顺序的。 不知何故,在控制台语句“应该首先调用”之前调用事件回调
答案 0 :(得分:2)
我无法确认这一点,但我强烈怀疑这是由控制台与页面加载过程之间的交互引起的。如果仔细观察,您会发现导航是在创建新Document对象之前执行的。如果你假设
然后记录的消息是旧文档中的残留物,显示在新的控制台日志中。
尝试为document
提供任意属性:
console.log("should have been called first, extra >>", document.extra);
function toggleTask () {
var msg;
if (document.hidden) {
msg = "hidden.. stop running expensive task";
} else {
msg = "not hidden.. page has focus, begin running task";
}
console.log(msg + ", extra >>", document.extra);
}
document.addEventListener('visibilitychange', toggleTask);
window.addEventListener("unload", function () {
console.log("called last, extra >>", document.extra);
});
document.extra = true;
第一次导航到页面日志
应首先调用,额外&gt;&gt;未定义
我无法重现第一页加载时获得的第二行。
重新加载操作添加
隐藏..停止运行昂贵的任务,额外&gt;&gt;真正
叫做last,extra&gt;&gt;真正
应首先调用,额外&gt;&gt;未定义
如果您离开页面,前两行也会显示在下一页。 (在Chrome中也通过历史记录:后退操作,在FF中仅用于真正的新页面加载)
很明显,对visibilitychange
事件侦听器的调用发生在旧文档的上下文中,但之后只能用新的Document对象替换它。
作为缓解措施,您可以在页面卸载前删除事件侦听器:
window.addEventListener("beforeunload", function () {
document.removeEventListener('visibilitychange', toggleTask);
});