javascript - 为什么 window.requestAnimationFrame 在页面刷新后不能立即工作?
问题描述
在我正在编码的项目中,我使用 window.requestAnimationFrame 以便在每次单击按钮时重复动画。不过我很困惑,因为刷新页面后,如果我单击按钮两次,第二次动画就不会发生。如果我在单击按钮之前单击页面上的其他内容,它仅在第二次有效,但如果我在刷新后立即单击它,则不会。这是单击按钮时的一些代码,但如果您需要更多代码,我可以提供。在此先感谢您的帮助!
submitNewPlunderForm.onclick = () => {
let users = JSON.parse(localStorage.users);
let username = newPlunderFormUsername.value;
if (users[username] === undefined) {
newPlunderFormUsername.style.border = "1.5px solid #eb3a34";
newPlunderFormUsername.style.boxShadow = "none";
newPlunderFormUsername.style.transition = "none";
window.requestAnimationFrame(function() {
newPlunderFormUsername.style.transition = "box-shadow 200ms";
newPlunderFormUsername.style.boxShadow = "0 0 5px #eb3a34";
});
解决方案
当页面加载后第一个 rAF 回调触发在不同的实现中变化很大时,并且实际上并没有任何规范,文档必须在回调可以触发之前完全激活,但是浏览器可以添加他们想要的任何延迟。
根据记忆,在 Firefox 中,调用后可能需要大约 20 毫秒,requestAnimationFrame
即使使用 60FPS 监视器(即它等待大约两帧),而在 Chrome 上它可能几乎同步发生。
此外,大多数现代浏览器都会将点击事件限制为动画帧速率,因此在浏览器触发任何重排之前,您的两个调用可能发生在同一个事件循环帧中。
最后,Chrome 有很多 bug。
但无论如何,对于您正在做的事情,您根本不需要 rAF,只需同步触发回流:
submitNewPlunderForm.onclick = () => {
let users = JSON.parse(localStorage.users);
let username = newPlunderFormUsername.value;
if (users[username] === undefined) {
newPlunderFormUsername.style.border = "1.5px solid #eb3a34";
newPlunderFormUsername.style.boxShadow = "none";
newPlunderFormUsername.style.transition = "box-shadow 200ms";
newPlunderFormUsername.offsetWidth; // force reflow
newPlunderFormUsername.style.boxShadow = "0 0 5px #eb3a34";
}
});
const newPlunderFormUsername = document.createElement("input");
document.body.append(newPlunderFormUsername);
newPlunderFormUsername.style.boxShadow = "none";
newPlunderFormUsername.style.transition = "box-shadow 2000ms";
newPlunderFormUsername.offsetWidth; // force reflow
newPlunderFormUsername.style.boxShadow = "0 0 5px #eb3a34";
推荐阅读
- php - PHP 模数运算符在计算器中不起作用
- javascript - 如何将所有路由重定向到nest.js中的index.html(Angular)?
- java - 如何从 Windows 上的 Java 控制台应用程序中确定当前活动的代码页?
- java - 我可以使用哪些命令来查看详细信息
某种Java类? - sql - 内部连接三个表并从其中两个表中选择一列时,SELECT 语句不返回任何结果
- python-3.x - 为什么在 Python 中读取文件时撇号(“'”)会变成▒?
- java - Android WallpaperManager 方法“软砖化”用户的手机并导致设备无响应
- laravel-5.1 - 有什么方法可以绕过 Laravel 上的 Model::created() 事件吗?
- bash - 阻止失败的假脱机创建文件?
- qemu - 错误:不存在 DTC (libfdt) 版本 >= 1.4.2。请安装 DTC (libfdt) 开发包