在requestAnimationFrame出現(xiàn)之前,我們一般都用setTimeout和setInterval,那么html5為什么新增一個(gè)requestAnimationFrame,他的出現(xiàn)是為了解決什么問(wèn)題?
優(yōu)勢(shì)與特點(diǎn):
1)requestAnimationFrame會(huì)把每一幀中的所有DOM操作集中起來(lái),在一次重繪或回流中就完成,并且重繪或回流的時(shí)間間隔緊緊跟隨瀏覽器的刷新頻率
2)在隱藏或不可見(jiàn)的元素中,requestAnimationFrame將不會(huì)進(jìn)行重繪或回流,這當(dāng)然就意味著更少的CPU、GPU和內(nèi)存使用量
3)requestAnimationFrame是由瀏覽器專門為動(dòng)畫(huà)提供的API,在運(yùn)行時(shí)瀏覽器會(huì)自動(dòng)優(yōu)化方法的調(diào)用,并且如果頁(yè)面不是激活狀態(tài)下的話,動(dòng)畫(huà)會(huì)自動(dòng)暫停,有效節(jié)省了CPU開(kāi)銷
一句話就是:這玩意性能高,不會(huì)卡屏,根據(jù)不同的瀏覽器自動(dòng)調(diào)整幀率。如果看不懂或者不理解,也沒(méi)有什么關(guān)系,這玩意跟瀏覽器渲染原理有關(guān)。我們先學(xué)會(huì)使用它!
如何使用requestAnimationFrame?
使用方式跟定時(shí)器setTimeout差不多,不同之處在于,他不需要設(shè)置時(shí)間間隔參數(shù)
var timer = requestAnimationFrame( function(){
console.log( '定時(shí)器代碼' );
} );
參數(shù)是一個(gè)回調(diào)函數(shù),返回值是一個(gè)整數(shù),用來(lái)表示定時(shí)器的編號(hào).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.onload = function(){
var aInput = document.querySelectorAll( "input" ),
timer = null;
aInput[0].onclick = function(){
timer = requestAnimationFrame( function say(){
console.log( 1 );
timer = requestAnimationFrame( say );
} );
};
aInput[1].onclick = function(){
cancelAnimationFrame( timer );
}
}
</script>
</head>
<body>
<input type="button" value="開(kāi)啟">
<input type="button" value="關(guān)閉">
</body>
</html>
cancelAnimationFrame用來(lái)關(guān)閉定時(shí)器
這個(gè)方法需要處理兼容:
簡(jiǎn)單的兼容:
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
如果瀏覽器都不認(rèn)識(shí)AnimationFrame,就用setTimeout兼容.
運(yùn)用3種不同的定時(shí)器(setTimeout, setInterval, requestAnimationFrame)實(shí)現(xiàn)一個(gè)進(jìn)度條的加載
一、setInterval方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div{
width:0px;
height:40px;
border-radius:20px;
background:#09f;
text-align:center;
font:bold 30px/40px '微軟雅黑';
color:white;
}
</style>
<script>
window.onload = function(){
var oBtn = document.querySelector( "input" ),
oBox = document.querySelector( "div" ),
timer = null, curWidth = 0,
getStyle = function( obj, name, value ){
if( obj.currentStyle ) {
return obj.currentStyle[name];
}else {
return getComputedStyle( obj, false )[name];
}
};
oBtn.onclick = function(){
clearInterval( timer );
oBox.style.width = '0';
timer = setInterval( function(){
curWidth = parseInt( getStyle( oBox, 'width' ) );
if ( curWidth < 1000 ) {
oBox.style.width = oBox.offsetWidth + 10 + 'px';
oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
}else {
clearInterval( timer );
}
}, 1000 / 60 );
}
}
</script>
</head>
<body>
<div>0%</div>
<p><input type="button" value="ready!Go"></p>
</body>
</html>
![](/d/20211016/2784e3517ac83fbcde40a1b3590314d2.gif)
二、setTimeout方式
<script>
window.onload = function(){
var oBtn = document.querySelector( "input" ),
oBox = document.querySelector( "div" ),
timer = null, curWidth = 0,
getStyle = function( obj, name, value ){
if( obj.currentStyle ) {
return obj.currentStyle[name];
}else {
return getComputedStyle( obj, false )[name];
}
};
oBtn.onclick = function(){
clearTimeout( timer );
oBox.style.width = '0';
timer = setTimeout( function go(){
curWidth = parseInt( getStyle( oBox, 'width' ) );
if ( curWidth < 1000 ) {
oBox.style.width = oBox.offsetWidth + 10 + 'px';
oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
timer = setTimeout( go, 1000 / 60 );
}else {
clearInterval( timer );
}
}, 1000 / 60 );
}
}
</script>
三、requestAnimationFrame方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div{
width:0px;
height:40px;
border-radius:20px;
background:#09f;
text-align:center;
font:bold 30px/40px '微軟雅黑';
color:white;
}
</style>
<script>
window.onload = function(){
var oBtn = document.querySelector( "input" ),
oBox = document.querySelector( "div" ),
timer = null, curWidth = 0,
getStyle = function( obj, name, value ){
if( obj.currentStyle ) {
return obj.currentStyle[name];
}else {
return getComputedStyle( obj, false )[name];
}
};
oBtn.onclick = function(){
cancelAnimationFrame( timer );
oBox.style.width = '0';
timer = requestAnimationFrame( function go(){
curWidth = parseInt( getStyle( oBox, 'width' ) );
if ( curWidth < 1000 ) {
oBox.style.width = oBox.offsetWidth + 10 + 'px';
oBox.innerHTML = parseInt( getStyle( oBox, 'width' ) ) / 10 + '%';
timer = requestAnimationFrame( go );
}else {
cancelAnimationFrame( timer );
}
} );
}
}
</script>
</head>
<body>
<div>0%</div>
<p><input type="button" value="ready!Go"></p>
</body>
</html>