私は、jQueryでよく知られている「requestAnimationFrame」の削除を解決するためのさまざまなアプローチに取り組んでいます。ここで、 animateは、今後のrequestAnimationFrameAPIではなくsetTimeout/setIntervalを使用するように戻されました。もちろん、これにより、そのページのブラウザタブにフォーカスがないときにアニメーションがキューに入れられるという既知の問題が発生します(ページのタブにフォーカスがないときにアニメーションが停止するというこの効果が必要なため、問題になります)。1つの解決策は、実際の「requestAnimationFrame」のクロスブラウザーrequestAnimFrameシムですべてをラップすることです。別の解決策は、アニメーション要素の一意のIDとタイムスタンプを生成し、ウィンドウがフォーカスされているときにのみアニメーションを実行することです。
これは、フォーカスリスナーとIDパスの2番目のアプローチで私が抱えていた苛立たしい問題の迅速で汚いデモです:http: //jsfiddle.net/bcmoney/NMgsc/17
更新(主な問題は解決されました):http://jsfiddle.net/bcmoney/NMgsc/
必要最低限のコード:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>window.focus listener EXAMPLE - jsFiddle demo by bcmoney</title>
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script>
<style type='text/css'>
body { overflow:hidden; }
#container { width:100%; height:100%; }
#animated { width:120px; position:absolute; left:2px; top:20px; padding:50px; background:skyblue; color:white }
</style>
<script type='text/javascript'>//<![CDATA[
$(function(){
var animation = 1;
var startTime = undefined;
var FPS = 60; //frames per second
var AVAILABLE_WIDTH = $("#container").width() || "800px";
var animation = null;
var FOCUSED = false;
var timestamp = new Date().getTime();
var PAGE_ID = $("body").attr("id") + "-animated-"+timestamp;
function continueScrolling(p) {
console.log('FUNCTION p: '+p);
if (FOCUSED === true && p === PAGE_ID) {
animation = setTimeout(scrollRight.bind(p), FPS);
} else {
clearTimeout(animation);
$('#animated').stop(true, true);
}
}
var scrollRight = function(p) {
time = +new Date;
startTime = (startTime !== undefined) ? startTime : time-FPS;
move = ((time - startTime)/10 % AVAILABLE_WIDTH)+"px";
console.log('P:'+p+' | T:'+time+' | ST:'+startTime+' | W:'+AVAILABLE_WIDTH+'\n'+move);
$('#animated').animate({
"left":move
},
1000/FPS,
"linear",
function() {
console.log('CALLBACK p: '+p);
continueScrolling(p);
}
);
}
$(window).blur(function(){
FOCUSED = false;
$('#stop').click();
});
$(window).focus(function(){
FOCUSED = true;
$('#start').click();
});
$('#start').click(function() {
scrollRight(PAGE_ID);
});
$('#stop').click(function() {
$('#animated').stop(true, true);
clearTimeout(animation);
});
});//]]>
</script>
</head>
<body id="slider">
<a id="start" href="#start">Start</a> | <a id="stop" href="#stop">Stop</a>
<div id="container">
<div id="animated">Animated content</div>
</div>
</body>
</html>
私は最近、一意のIDが必要ない可能性があることに気づき、今のところシムアプローチを支持して、フォーカスリスナーでそれらの最初の調査を破棄しました。ただし、このいじくり回しは、jQueryの別の潜在的な問題(またはおそらくそれについての私の理解)を指摘し、パラメーターをjQueryのコールバック関数に渡し、パラメーターの値がアニメーションのコンテキストを通じて確実に伝播されるようにします。
ご覧のとおり、値「p」が渡されなくなったため、アニメーションが開始および停止します。私はクロージャーの専門家ではありませんが、$。proxyを使用するだけでなく、1つのソリューションとしてここで提案されているのを見ました(休憩してSOに投稿する前にここから試しました)。API呼び出しをチェーンしている場合でも、$。 ajaxまたは$ .getJSONコールバックでこの問題が発生したことはありませんが、何らかの理由で、continueScrolling関数への後続の呼び出しの値を維持するためのコールバックパラメーターを取得できないようです。一部のJS/jQuery忍者からの助けをいただければ幸いです...