我最近看了杰克·阿奇博尔德的演讲。他在演讲中举了一个例子,他说要两次使用requestAnimationFrame来延迟应用CSS样式来执行CSS动画。
请参见https://youtu.be/cCOL7MC4Pl0?t=1337
我转载了示例进行测试,但是没有运气:
提出了杰克·阿奇博尔德的解决方案。使用两层嵌套的requestAnimationFrame
但是它似乎不适用于我。为什么?
这是应该应该起作用但不能起作用的代码段:
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
box.style.transition = 'transform 1s ease-out';
requestAnimationFrame(()=>{
requestAnimationFrame(()=>{
box.style.transform = 'translateX(250px)';
});
});
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
}
<div id="box">box</div>
答案 0 :(得分:2)
像这样吗?
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
requestAnimationFrame(()=>{
box.style.transition = 'transform 1s ease-out';
requestAnimationFrame(()=>{
box.style.transform = 'translateX(250px)';
});
});
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
}
<div id="box">box</div>
答案 1 :(得分:0)
我真的很讨厌视频,所以我没有完全检查它,但是可以肯定的是,他们在调用该JavaScript之前已经翻译了#box
元素。
如果没有,那么它将在一帧内实际执行从translateX(0)
到translateX(1000px)
的过渡,并且在从任何位置(可能从左开始不远处)过渡到{{ 1}}。
因此,要解决此问题,可以在CSS中设置初始translateX(250px)
值。
translateX
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
box.style.transition = 'transform 1s ease-out';
requestAnimationFrame(()=>{
requestAnimationFrame(()=>{
box.style.transform = 'translateX(250px)';
});
});
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
transform: translateX(1000px);
}
现在,您实际上不应该使用双重requestAnimationFrame hack。而是identify the problem and use a proper fix(即强制重排)。
You have to scroll to the right now.
<div id="box">box</div>
const box = document.getElementById("box");
box.addEventListener("click", ()=>{
box.style.transform = 'translateX(500px)';
box.offsetWidth; // force reflow so our box is translated to initial position
box.style.transition = 'transform 1s ease-out';
box.style.transform = 'translateX(250px)';
});
#box {
background-color: salmon;
height: 100px;
width: 100px;
cursor: pointer;
}