0

私はこの機能を持っています

function createSlidingGallery(){
    gallery_position = parseInt(jQuery(".imageWrapper.default").attr("rel"));
    gallery_position_min = 0;
    gallery_position_max = parseInt(jQuery("#galleryEl .sig_thumb a").size() - 1);
    var galleryWrapper = document.createElement("div");
    galleryWrapper.className = "sGalleryWrapper";
    for (var i = 0; i < gallery_position_max; i++) {
        var slide = document.createElement("div");
        slide.className = "slide slide"+(i);
        slide.setAttribute('rel', i);
        galleryWrapper.appendChild(slide);
    };
    jQuery(".imageWrapper.top").append(galleryWrapper);


//HERE COMES THE PROBLEM PART

    for (var i = 0; i < gallery_position_max; i++) {
        var position = i;

//THE CALLBACK ACTUALLY USES THE SAME CONTEXT FOR ALL PARTICULAR CALLS SO THAT THE POSITION VALUE HOLDS THE MAXIMUM VALUE IN ALL INSTANCES

        loadImage(position, false, function(index){
            console.log(index);
            jQuery(".slide"+position).css({
                'background': 'url('+backgroundImages[index].src+')'
            });

        });
    };
    hideLoadingDC();


}

すべきことは、動的に作成された要素に画像を非同期的にロードすることです。実際にすべての要素を作成し、画像もロードします。ただし、画像をプリロードし、この画像が既にロードされて適切にキャッシュされているという情報を保存するための loadImage という関数があります。ロードされた画像を処理し、適切な要素の背景として設定するコールバック関数で呼び出しています。したがって、要素に関する情報 (ポインター、インデックス/位置など) を保持する必要があります。今、私はそのインデックスを関数に伝播しようとしていますが、しばらくしてからコールバック関数が呼び出されるため、位置変数にはすでに他の値があります(forループは実際に通過し、コールバックのすべての呼び出しで最大値に設定されます) )

loadImage 関数を変更して位置を別の属性として追加できることはわかっていますが、他のソリューションを好むでしょう。loadImage 関数を変更したくありません。

4

2 に答える 2

2

ヘルパー関数を使用して、position変数の新しいスコープを作成できます。

function makeGalleryCallback(position) {
   return function(index){
         console.log(index);
         jQuery(".slide"+position).css({
                'background': 'url('+backgroundImages[index].src+')'
             });
      };
}

function createSlidingGallery(){
    ...
    for (var i = 0; i < gallery_position_max; i++) {
       loadImage(i, false, makeGalleryCallback(i));
    }
    ...
}
于 2012-05-07T18:05:00.067 に答える
2

問題は、すべてのコールバック関数が同じ i 値を参照しており、反復時に値を実際に追跡していないことです。そのため、i の異なる値ごとに新しい参照を作成する新しいスコープ (クロージャー) を作成する必要があります。

関数を使用してJSで新しいスコープを作成できます。コードを匿名関数でラップし、i の異なる値ごとにその関数を実行する必要があります。

for (var i = 0; i < gallery_position_max; i++) {
    var position = i;
    loadImage(position, false, (function(index){
      return function(){
        console.log(index);
        jQuery(".slide"+position).css({
            'background': 'url('+backgroundImages[index].src+')'
        });
      };})(i));
};

   

于 2012-05-07T18:49:35.423 に答える