页面可见性 API 是不是在脚本中的任何其他内容之前运行
Posted
技术标签:
【中文标题】页面可见性 API 是不是在脚本中的任何其他内容之前运行【英文标题】:Does page visibility API runs way before before anything else in script页面可见性 API 是否在脚本中的任何其他内容之前运行 【发布时间】:2017-11-05 07:36:15 【问题描述】:下面的代码给出的输出为
应该先被调用>> false
hidden.. 停止运行昂贵的任务
它似乎是第一次按顺序运行以进一步重新加载页面,它以某种方式缓存我猜想的事件监听器..并给出以下输出。
hidden.. 停止运行昂贵的任务
应该先被调用>> false
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>
只需使用上面的 sn-p 代码创建一个 html 页面。 打开浏览器控制台。您将依次看到控制台语句。 现在,如果你重新加载这个 html 页面,语句就会乱序。 在控制台语句“应该首先调用”之前以某种方式首先调用事件回调
【问题讨论】:
您能否提供更多有关执行此操作的上下文?它是在页面上的脚本标签内,还是在 document.ready() 回调内等等? 都试过了,在onload里面,文件准备好了,或者只是在脚本标签里,结果一样 很遗憾,我无法重复您的问题。据我所知,控制台语句应该在事件监听器被附加之前触发(更不用说在事件触发之前)。尝试将 .warn() 更改为 .log() 以确保它不会影响事物,并尝试不同的浏览器。看看行为是否改变。 不。我复制了您的代码,按照您的要求进行了刷新。首先得到“应该首先调用>> false”,然后随着可见性的变化,可见性改变消息。刷新后一样。 你测试的是什么浏览器? 【参考方案1】:我无法真正确认这一点,但我强烈怀疑这是由控制台和页面加载过程之间的交互引起的。如果仔细观察,您会发现导航是在创建新的 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;
第一次导航到页面日志
应该先被调用,extra >> undefined
我无法重现您在第一页加载时得到的第二行。
重新加载动作添加
hidden.. 停止运行昂贵的任务,额外的 >> true 最后调用,额外 >> true 应该先被调用,extra >> undefined
如果您离开页面,前两行也会显示为下一页。 (在 Chrome 中也可以通过 History:Back 操作,在 FF 中仅用于真正的新页面加载)
很明显,对 visibilitychange
事件侦听器的调用发生在旧文档的上下文中,但它只是在之后才被新的 Document 对象替换。
作为一种缓解措施,您可以在页面卸载之前移除事件监听器:
window.addEventListener("beforeunload", function ()
document.removeEventListener('visibilitychange', toggleTask);
);
【讨论】:
谢谢.. 这很有帮助和信息量很大,你第一次没有得到第二行可能是因为你在 console.log 函数中使用了undefined
属性和,
,你能试试吗+
喜欢console.log(msg + ", extra >>"+ document.extra);
您在卸载之前删除事件侦听器是正确的,使其行为“正确”(按照说法)。感谢您的回答。现在对我来说很清楚了。以上是关于页面可见性 API 是不是在脚本中的任何其他内容之前运行的主要内容,如果未能解决你的问题,请参考以下文章