2

非同期でロードするコンテンツの URL の配列があります。

var toLoad = ['snippet1.html', 'snippet2.html', ... ];

<div>各スニペットを AJAX で読み込んで、それを parentに追加し、配列内のコンテンツの順序を維持しようとしています。私のコードの残りの部分が設定されている方法のため (およびパフォーマンス上の理由から)、this similar questionへの回答で示唆されているように、呼び出しを使用して、またはチェーン呼び出しによって、同期的にロードしたくありません。代わりに、AJAX コールバック関数にロジックを入れて、インデックスに基づいて、読み込まれたスニペットを正しく配置したいと考えています。async:false.ajax()

次のコードが機能します。

var $parent = $('#mydiv');
toLoad.forEach(function(url, i) {
    // load snippet
    $.get(url, function(snippet) {
        // attach order to DOM element
        snippet = $(snippet).data('order', i);
        // find the sibling with the next lowest order number
        var $prev = $parent
            .children()
            .filter(function() {
                return $(this).data('order') < i
            })
            .last();
        if ($prev[0]) snippet.insertAfter($prev); 
        else $parent.prepend(snippet);
    });
});

……でも、もったいない。.data()特に、DOM 要素に;で順序を付けるのは好きではありません。これは醜いように思えます。私ができることなら、これを DOM に貼り付けたくありません。

定義済みの順序でコンテンツを div に非同期にロードするという目標を達成するためのより良い方法はありますか?

4

2 に答える 2

3

次の再帰が開始される前に、1 つが終了するまで待機する単純な再帰があります。

var toLoad = ['snippet1.html', 'snippet2.html', ....];
var $parent = $('#mydiv');
var i = 0;

getSnippet(toLoad[i]);

function getSnippet(url) {
    $.get(url, function(snippet) {
        $parent.append(snippet);
        if (i<toLoad.length) getSnippet(toLoad[i++]);
    });
}​

次に、それらをすべて一度に実行し、それらを配列に貼り付け、done()関数を次々に実行して、要素が順番に挿入されるようにします。

var toLoad = ['snippet1.html', 'snippet2.html', 'snippet3.html'];
var $parent = $('#mydiv');
var gets = [];

toLoad.forEach(function(url, i) {
    var XHR = $.get(url);
    gets.push(XHR);
});

gets[0].done(function(snippet) {
     $parent.append(snippet);
     gets[1].done(function(snippet) {
         $parent.append(snippet);
         gets[2].done(function(snippet) {
             $parent.append(snippet);
         });
     });
});
​

多くの ajax 呼び出しを行う場合、これはおそらくある種のループで実行できます。

それからdefered オブジェクトpromisesがあります:

$.when($.get(toLoad[0]), 
       $.get(toLoad[1])
       $.get(toLoad[2])
      ).done(function(value1, value2, value3) {
      // value1 etc. are arguments resolved for the ajax requests, respectively
      // arguments are [ "success", statusText, jqXHR ]
        $parent.append(value1[2]+value2[2]+value3[2]);
      }
});
于 2012-05-21T21:28:54.633 に答える
2

主な不満が.data()を使用している場合は、domノード要素を値に関連付ける独自の配列を維持できます。

var map = [
    {order: 5, nodeReference: ...},
    {order: 9, nodeReference: ...},
    {order: 1, nodeReference: ...}
];
function data(node) {
    // loop through map, comparing to nodeReference to get the order 
}

//その後 ...

    .filter(function() {
        return data(this) < i
    })

domに何かを追加するときにマップに追加する必要があることを除いて、コードはほとんど同じままです。

今のように、ロードされたらすぐにdomに徐々に追加していきたいと思います。すべてが読み込まれるまで、または順番に追加するまで待ちません。あなたが今しているように、注文は最終的にはうまくいくようにしましょう。これは、WebブラウザがWebページに画像をロードする方法であり、それには深い理由があります。

于 2012-05-21T20:46:49.770 に答える