0

いくつかの値をループし続ける方法を探しています。ターゲット要素のデータセットから値(ファイル)を取得する単純なajaxロードスクリプトを使用しています。ファイルの再ロードは XXXX 秒ごとに行われるため、ファイルが何度もロードされますが、さらにファイルが存在する場合は、それらすべてをループし、再ループする必要があります....無限

以下の例は基本的なアイデアです。文字列を分割して最初の文字列から始めますが、これをループして (最善の方法)、ループを維持するにはどうすればよいですか。

HTML

<div id="target" data-load="file1.php | file2.php | file3.php"></div>

jQuery

var fileTo = $('#target').data('widget-load').split("|");

setInterval(function(){
   $('#target').load(fileTo[0])
},1000);
4

4 に答える 4

0

@Diode:無限ループの場合は、シフト&&プッシュの方が適しています。それらを忘れました。その場合、私は次のことを提案します:

var intervalId = setInterval((function(theArray)
{
    var target = $('#target');
    var current;
    return function ()
    {
        current = theArray.shift();
        target.load(current);
        theArray.push(current);
    };
})($('#target').data('widget-load').split("|")),1000);

これを試して:

var intervalId = setInterval((function(theArray)
{
    var target = $('#target');//only search for this once, not on every call
    //to make infinite loop, copy the array
    var resetArr = theArray.slice(0);//use slice, if not a reference is assigned and both arrays will be altered 
    //Name is not required, if you want to use a name, pick a better one, next might be reserved (not sure)
    //best go for nextInterval, chose this one for explanation
    return function next()
    {
        //get first element, theArray is now 1 shorter
        target.load(theArray.splice(0,1)[0]);
        if (theArray.length === 0)
        {//no more files left -> this stops the interval
            //clearInterval(intervalId);
            //intervalId = null;
            //restore the array, the loop starts from file1 again --> infinite loop
            theArray = resetArr.slice(0);//copy the original value
        }
    }
})($('#target').data('widget-load').split("|")),1000);

これは少し密度が高いかもしれませんが、Chromeコンソールで単純な1行バージョンを試しました。

foo = setInterval((function(arr){ return function(){alert(arr.splice(0,1)[0]); if (arr.length === 0){ clearInterval(foo);}};})([1,2,3]),1000);

そしてそれは魅力のように機能します。
使い方:

intervalId間隔のermidを保持します...一種の参照。それが設定されている限り、関数はごとに呼び出され1000msます。単純な関数を最初の引数として渡す代わりに、関数を作成してすぐに呼び出します。名前のない関数()に渡した引数には、無名関数の戻り値である、theArrayという関数からアクセスできます。関数内で作成されるため、母親が戻った後でも、母親関数nextのすべての変数にアクセスできます。これは、間隔の実際のコールバックである関数を除いて、の値が他のすべての場所の範囲外であることを意味します。の価値を妨げるものは何もありません
theArraynexttheArray、外部コードで上書きできるものはないため、グローバルを使用する場合に比べて非常に安全なアプローチになります。
同じことが変数にも当てはまります。匿名のマザーtarget関数で宣言および初期化され、一度呼び出されてからGCされます。ただし、変数は存続し、jQueryオブジェクトを参照します。DOMはその要素に対して一度だけ検索されましたが、関数への新しい呼び出しはすべてそのオブジェクトにアクセスできます。これを1回実行すると、速度の差はわずかになります。これを常に実行すると、スクリプト(はるかに)効率的になります。next

したがって、間隔:1000msごとにnext呼び出されます。theArray作成者(無名関数)の引数()であった配列から最初の値をシフトします。その配列が空の場合、clearInterval関数が呼び出されてロットが停止します。すべてのファイルがロードされ、続行しても意味がありません。
これが発生するとすぐtheArrayに、、- nextfunction、および他のすべての変数(target)がスコープ外になるため、グローバル変数はなく、メモリのすてきでクリーンなチャンクになります。これは常に良いことです。このコードはイベントハンドラーの一部としてトリガーされると想定しています。この場合、これをコピーしてハンドラーに貼り付けるだけで、グローバルは作成されません。

このコードがグローバルスコープの一部になる場合は、すべてを自己呼び出し関数でラップするだけで、グローバルを簡単に回避できます。

(function()
{
    var intervalId = setInterval((function(theArray)
    {
        //...
    })($('#target').data('widget-load').split("|")),1000);
})();

そして、あなたはすべて準備ができています。私見ですが、これはこの問題に対する最良で最も安全で最もJS志向のアプローチです。JavaScriptはすべて関数に関するものであり、それらを活用すればするほど、言語はそれをより好むようになります。実際、その隠された表現力を明らかにすることで、それを感謝します。

この回答を使用しないことにした場合でも、クロージャや関数スコープを最大限に活用する方法などを読んでください。あなたはすぐにあなた自身が全く新しい方法であなたのコードを書いていることに気付くでしょう、約束してください:)

于 2012-08-16T16:42:18.397 に答える
0
var fileTo = $('#target').data('widget-load').split("|");

setInterval(function(){
   var file = fileTo.shift();   // `shift` gives the file at 0
   $('#target').load(file);     // load it
   fileTo.push(file);           // `push` adds it at the end of the array
},1000);
于 2012-08-16T17:12:15.577 に答える
0

setTimeout("function",delay) を使用して、ミリ秒の遅延で同じ関数を呼び出し続けることができます。

于 2012-08-16T16:31:10.290 に答える
-1
var $target = $('#target'),
    fileTo = $target.data('widget-load').split("|"),
    i = 0;

setInterval(function(){
   $target.load(fileTo[i]);
   i++;
   if (i === fileTo.length)
      i = 0;
},1000);
于 2012-08-16T16:31:43.963 に答える