Quando se trata de animação, dizem que setInterval
é uma má ideia. Porque, por exemplo, o loop será executado independentemente de qualquer outra coisa que esteja acontecendo, em vez de ceder educadamente como faria requestAnimationFrame
. Além disso, alguns navegadores podem “jogar catchup” com um loop setInterval, onde uma guia inativa pode estar enfileirando iterações e, em seguida, executá-los todos muito rapidamente para recuperar o atraso quando se tornar ativo novamente.
Se você gostaria de usar setInterval
, mas quer a cortesia de desempenho requestAnimationFrame
, a internet tem algumas opções disponíveis!
De Serguei Shimansky:
var requestInterval = function (fn, delay) ( var requestAnimFrame = (function () ( return window.requestAnimationFrame || function (callback, element) ( window.setTimeout(callback, 1000 / 60); ); ))(), start = new Date().getTime(), handle = (); function loop() ( handle.value = requestAnimFrame(loop); var current = new Date().getTime(), delta = current - start; if (delta >= delay) ( fn.call(); start = new Date().getTime(); ) ) handle.value = requestAnimFrame(loop); return handle; );
Veja o comentário para as variações, como limpar o intervalo e definir e limpar tempos limite.
Esta foi uma variação da versão de Joe Lambert:
window.requestInterval = function(fn, delay) ( if( !window.requestAnimationFrame && !window.webkitRequestAnimationFrame && !(window.mozRequestAnimationFrame && window.mozCancelRequestAnimationFrame) && // Firefox 5 ships without cancel support !window.oRequestAnimationFrame && !window.msRequestAnimationFrame) return window.setInterval(fn, delay); var start = new Date().getTime(), handle = new Object(); function loop() ( var current = new Date().getTime(), delta = current - start; if(delta >= delay) ( fn.call(); start = new Date().getTime(); ) handle.value = requestAnimFrame(loop); ); handle.value = requestAnimFrame(loop); return handle; ) window.clearRequestInterval = function(handle) ( window.cancelAnimationFrame ? window.cancelAnimationFrame(handle.value) : window.webkitCancelAnimationFrame ? window.webkitCancelAnimationFrame(handle.value) : window.webkitCancelRequestAnimationFrame ? window.webkitCancelRequestAnimationFrame(handle.value) : /* Support for legacy API */ window.mozCancelRequestAnimationFrame ? window.mozCancelRequestAnimationFrame(handle.value) : window.oCancelRequestAnimationFrame ? window.oCancelRequestAnimationFrame(handle.value) : window.msCancelRequestAnimationFrame ? window.msCancelRequestAnimationFrame(handle.value) : clearInterval(handle); );
O que é mais detalhado em parte porque trata da prefixação do fornecedor. É muito provável que você não precise do prefixo do fornecedor. Consulte o suporte do navegador para requestAnimationFrame. Se você precisa de suporte para IE 9 ou Android 4.2-4.3, você não pode usar isso. O prefixo do fornecedor só ajuda em versões bastante antigas do Safari e Firefox.
E mais um da StackExchange:
window.rInterval=function(callback,delay) ( var dateNow=Date.now, requestAnimation=window.requestAnimationFrame, start=dateNow(), stop, intervalFunc=function() ( dateNow()-start