作者:人心城府深我如z何故做清纯 | 来源:互联网 | 2022-12-01 19:43
我在页面上有一堆长时间运行的CSS动画.我想在用户切换到另一个选项卡时暂停它们,并在用户再次返回原始选项卡时恢复它们.为简单起见,我不打算在此时使用跨浏览器解决方案; 让它在Chrome中运行应该足够了.
document.addEventListener("visibilitychange", function() {
if (document.hidden) {
document.querySelector("#test").classList.add("paused");
} else {
document.querySelector("#test").classList.remove("paused");
}
});
div#test {
width: 50px;
height: 50px;
background-color: red;
position: absolute;
left: 10vw;
animation-name: move;
animation-duration: 5s;
animation-fill-mode: forwards;
animation-timing-function: linear;
}
@keyframes move {
to {
left: 90vw
}
}
.paused {
animation-play-state: paused !important;
-webkit-animation-play-state: paused !important;
-moz-animation-play-state: paused !important;
}
上面的代码水平移动一个红色矩形.矩形完成动画需要5秒钟.
问题:动画启动后,切换到另一个浏览器选项卡; 经过一段时间(超过5秒)后切换回第一个标签.
预期结果:矩形从其停止的位置继续其路径.
实际结果:矩形出现在最终目的地并停止的大部分时间.有时它按预期工作.视频演示了这个问题.
我打了不同的价值观animation-fill-mode
和animation-timing-function
,但结果总是相同的.正如rv7 指出的那样,在CodePen,JSFiddle,JSBin和stackoverflow JS工具中共享示例会影响结果,因此最好直接针对本地HTTP服务器上的静态页面进行测试(或使用下面的链接).
为方便起见,我已将上面的代码部署到Heroku.该应用程序是一个静态nodejs HTTP服务器,它运行在免费订阅上,因此第一次加载页面最多可能需要5分钟.针对此页面的测试结果:
FAIL Chrome 64.0.3282.167(官方版)(64位)Linux Debian Stretch(PC)
FAIL Chrome 70.0.3538.67(官方版)(64位)Windows 10(PC)
FAIL Chrome 70.0.3538.77(官方版)(32 -bit)Windows 7(PC)
FAIL Chrome 70.0.3538.77(官方版)(64位)OSX 10.13.5(Mac mini)
FAIL FF Quantum 60.2.2esr(64位)Linux Debian Stretch(PC)
OK Safari 11.1 .1(13605.2.8)(Mac mini)
该网页的曝光率API可以用窗口来代替focus
和blur
事件是这样的:
window.addEventListener("focus", function() {
document.querySelector("#test").classList.remove("paused");
});
window.addEventListener("blur", function() {
document.querySelector("#test").classList.add("paused");
});
然而,这种替换并不等同.如果页面包含IFRAME,则与其内容进行交互将触发主窗口上的事件focus
和blur
事件.在这种情况下执行任何制表符切换代码是不正确的.在某些情况下,这可能仍然是一个选项,所以我在这里部署了一个测试页面.结果略好一些:
FAIL Chrome 64.0.3282.167(官方版)(64位)Linux Debian Stretch(PC)
FAIL Chrome 70.0.3538.67(官方版)(64位)Windows 10(PC)
FAIL Chrome 70.0.3538.77(官方版)(32 -bit)Windows 7(PC)
FAIL Chrome 70.0.3538.77(官方版)(64位)OSX 10.13.5(Mac mini)
OK FF Quantum 60.2.2esr(64位)Linux Debian Stretch(PC)
OK Safari 11.1 .1(13605.2.8)(Mac mini)
此版本在Chrome 64位中比在Chrome 32位中更常失败.在Chrome 32位中,我在成功尝试20次后失败了1次.这可能与Chrome 32位安装在较旧的硬件上有关.
问题是:有没有办法在切换标签时可靠地暂停/恢复CSS动画?
1> rv7..:
您可以使用focus
和blur
事件而不是visibilitychange
事件,因为前者有更好的浏览器支持!
let box = document.querySelector('#test');
window.addEventListener('focus', function() {
box.style.animatiOnPlayState= 'paused';
});
window.addEventListener('blur', function() {
box.style.animatiOnPlayState= 'running';
});
或者,您也可以使用CSS类来执行此操作:
.paused {
animation-play-state: paused !important;
-webkit-animation-play-state: paused !important;
-moz-animation-play-state: paused !important;
}
let box = document.querySelector('#test');
window.addEventListener('focus', function() {
box.classList.remove('paused');
});
window.addEventListener('blur', function() {
box.classList.add('paused');
});
以上两种方式在CodePen,JSFiddle,JSBin等的iframe中不起作用; 在帖子结尾提供了一个可能的原因.但是,这是一个视频链接,显示代码如何在CodePen的调试模式下工作.
实例
确认:
谷歌浏览器v70.0.3538.67(官方版)(32位)
Firefox Quantum v62.0.3(32位)
Internet Explorer v11 +
代码无法在其中运行的可能原因iframe
:
当我尝试访问root window
(又名parent
对象,请注意它不是iframe window
)时,控制台中记录以下错误:
这意味着我无法访问root window
CodePen和其他人.因此,如果我无法访问它,我无法向其添加任何事件侦听器.