<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>requestAnimation</title>
<style type="text/css">
.container {
position: relative;
}
#percent {
display: inline-block;
width: 50px;
}
</style>
</head>
<body>
<h1>切到后台或其他浏览器tab,requestAnimation不再执行</h1>
<button id="requestAnimationFrame1">requestAnimationFrame1</button>
<button id="cancelAnimationFrame1">cancelAnimationFrame1</button>
<h1>requestAnimation演示动画</h1>
<div class="container">
<progress value=0 id="bar" max="100"></progress>
<span id="percent">0%</span>
<button id="requestAnimationFrame2">requestAnimationFrame2</button>
<button id="cancelAnimationFrame2">cancelAnimationFrame2</button>
</div>
<h1>requestAnimationFrame不是宏任务也不是微任务,而是浏览器提供的用于动画的特殊API</h1>
<p>requestAnimationFrame是浏览器的API,用于指示浏览器在下一次绘图周期时调用指定的函数更新动画。这个调用时机通常是浏览器刷新屏幕前的最后一刻,也就是说,它是同步于显示硬件的刷新频率的</p>
<p>如果涉及渲染页面, 如回流或重绘:执行顺序是promise-->requestAnimation-->setTimeout</p>
<p>如果不涉及渲染页面,如部分热更新(概率较小):执行顺序是promise-->setTimeout-->requestAnimation</p>
<p>requestAnimationFrame执行顺序分两种情况,如果微任务执行完之后页面发生了渲染则会马上执行requestAnimationFrame,否则会在微任务执行完后执行宏任务,再执行requestAnimationFrame</p>
<p>总结:浏览器的渲染机制决定了requestAnimation的执行顺序</p> <script type="text/javascript">
var id1, id2 = 0;
var raf1 = document.querySelector("#requestAnimationFrame1");
var caf1 = document.querySelector("#cancelAnimationFrame1");
var raf2 = document.querySelector("#requestAnimationFrame2");
var caf2 = document.querySelector("#cancelAnimationFrame2");
var bar = document.querySelector("#bar");
var percent = document.querySelector("#percent");
function changeTitle(timestamp) {
console.log(id1);
document.title = id1;
id1 = requestAnimationFrame(changeTitle);
}
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
cancelAnimationFrame(id1);
console.clear();
id1 = requestAnimationFrame(changeTitle);
}
})
raf1.onclick = function() {
id1 = requestAnimationFrame(changeTitle);
}
caf1.onclick = function() {
cancelAnimationFrame(id1);
}
function animate() {
if (id2 <= 100) {
bar.value = id2;
percent.innerText = id2 + "%";
id2 = requestAnimationFrame(animate);
}
}
raf2.onclick = animate;
caf2.onclick = function() {
cancelAnimationFrame(id2);
}
setTimeout(function(){
console.log("我是宏任务setTimeout", new Date().getTime())
},5)
requestAnimationFrame(function(){
console.log("我是requestAnimationFrame", new Date().getTime());
})
new Promise(function(resolve){
resolve('我是微任务Promise')
}).then(res=>{
console.log(res, new Date().getTime());
})
</script>
</body>
</html>
requestAnimation示例
于 2024-04-24 22:49:49 首次发布