window.requestAnimationFrame()的使用,處理更流暢的動畫效果


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. 用法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

簡單說明:

  1. 定義了一個立即執行函數,形成具備作用域,避免污染全局空間。
  2. 將功能函數掛在了window.
  3. 利用setTimeout和clearTimeout的異步實現相應的功能,不是為一種很好的結局方案。
  4. 如果對異步有疑問,可以查看我的另一篇博客js的執行機制


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM