https://blog.csdn.net/w2765006513/article/details/53843169
window.requestAnimationFrame()的使用
版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/w2765006513/article/details/53843169
1.前言
在說明這個js的api用法之前,我先給個效果以及源碼:
1. 頁面效果
2. 頁面源碼
2.說明
window.requestAnimationFrame()這個API是瀏覽器提供的js全局方法,針對動畫效果。
1)使用
- 用法1:
function animate() { //done(); requestAnimationFrame(animate); } requestAnimationFrame(animate);
注意函數里的requestAnimationFrame(animate)
有了這句話,就形成了遞歸調用,設置應為這個函數多用在持續的動畫中,可以自由處理要不要這句話。
2. 用法2:
var globalID; function animate() { // done(); 一直運行 globalID=requestAnimationFrame(animate); // Do something animate } globalID=requestAnimationFrame(animate);//開始 cancelAnimationFrame(globalID);//結束
2)優點:
瀏覽器可以優化並行的動畫動作,更合理的重新排列動作序列,並把能夠合並的動作放在一個渲染周期內完成,從而呈現出更流暢的動畫效果。
- 經過瀏覽器優化,動畫更流暢;
- 窗口沒激活時,動畫將停止,省計算資源;
3) 使用場景:
可以調節重新渲染,大幅提高網頁性能。其中最重要的,它可以將某些代碼放到下一次重新渲染時執行。避免短時間內觸發大量reflow。
function doubleHeight(element) { var currentHeight = element.clientHeight; window.requestAnimationFrame(function () { element.style.height = (currentHeight * 2) + 'px'; }); } elements.forEach(doubleHeight);
頁面滾動事件(scroll)的監聽函數,就很適合用這個api,推遲到下一次重新渲染。
$(window).on('scroll', function() { window.requestAnimationFrame(scrollHandler); });
最佳的應用場景還是在幀動畫里,可以大幅優化性能;
4)兼容性支持
為了避免老瀏覽器沒有提供這個api,可以先檢測,后處理,沒有提供api時,寫對應的函數掛在window下,以后的調用與正常情況一致。
網上大神的傑作
(function() { var lastTime = 0; var vendors = ['webkit', 'moz']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) { clearTimeout(id); }; }());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
簡單說明:
- 定義了一個立即執行函數,形成具備作用域,避免污染全局空間。
- 將功能函數掛在了window.
- 利用setTimeout和clearTimeout的異步實現相應的功能,不是為一種很好的結局方案。
- 如果對異步有疑問,可以查看我的另一篇博客js的執行機制