Загрузка изображения Jquery Ajax работает только после вставки оператора оповещения в функцию $ (window) .one. - PullRequest
0 голосов
/ 01 июля 2010

У меня особенная проблема.Я загружаю файл JSON, который содержит src, ширину и высоту нескольких изображений.

Я пытаюсь загрузить их в плагин плавного сценария jquery и автоматически прокручивать изображения.

Div "область просмотра" может вместить три изображения рядом.

Когда я впервые загружаю страницу, отображается только первое изображение.Если я перезагружаю его, отображаются первые три изображения, а остальные (всего их 11) загружаются, но плагин не прокручивается, поэтому вы их не видите.

Когда я вставляюСтрока alert («что угодно») в функции $ (window) .one, все работает нормально.

Я подозреваю, что это будет как-то связано с тем, когда загружаются изображения и когда запускается событие .load.

Вот код, который анализирует файлы JSON и создает строку HTML, которая добавляется к прокручиваемому div:

var aSectionImages = new Array;
var aImagesCount = new Array();
var aImagesLoaded = new Array();
var htmlString;
var jsonStyleImages = "images.json"
 var jsonNavImages = "imagesNav.json";
var scrollableArea = $("#scrollableArea");
$.getJSON(jsonNavImages, getNavIcons);
$.getJSON(jsonStyleImages, makeScroller);

function imageLoaded(imgSrc){
 var locId = (imageInSection(imgSrc)).replace(/\s|'/g, "_");
 if (aImagesLoaded[locId]===undefined){
  aImagesLoaded[locId] = 0;
 };     
 aImagesLoaded[locId] = aImagesLoaded[locId]+1;
 if (aImagesLoaded[locId]==aImagesCount[locId]){
  //alert("section" + locId);
  //$("#loaded").html(locId);
  //aSectionLoaded = {locId:"loaded"};

  //in theory, wait until all images in a section are loaded before
  //appending the HTML to the div:
  scrollableArea.append(htmlString);
 }
}

function imageInSection(src){
 var resultId=false;
 var locSrc = src.split("/");
 var locFileName = (locSrc[locSrc.length-1]);
 for (i = 0; i < aSectionImages.length; i++){
   for(j=0; j < aSectionImages[i].images.length; j++){
    tempSrc = aSectionImages[i].images[j].src.split("/");
    tempFileName = tempSrc[tempSrc.length-1];
    if (tempFileName == locFileName) {
     resultId = aSectionImages[i].id;
    }
   }
 }
 return resultId;
}

function makeScroller(data){
 aSectionImages = data;
 for (i=0; i<aSectionImages.length;i++){
  locData = aSectionImages[i];
  locId = locData.id.replace(/\s|'/g, "_");
  aImagesCount[locId] = locData.images.length;
  htmlString = "<div id=\"" + locId + "\">";

   for (j=0; j<locData.images.length; j++){
    oImage = new Image();
    $(oImage)
     .load(function(){
      imageLoaded(this.src);
    })
     .attr("src", locData.images[j].src);

     if (oImage.complete && oImage.naturalWidth !== 0){
     $(this).trigger("load");
     //$("#trigger").html(locData.images[j].src);
     //return false;
     }
    locImage = locData.images[j];
    locImage.id ? locImage.id = " id=\""+locImage.id+"\" " : locImage.id = "";
    htmlString += "<img height=\"" + locImage.height + "\"" + " width=\"" + locImage.width + "\"" + locImage.id + " src=\"" + locImage.src + "\" />";
   }       
 }

}

Вот частьплагин, который связан с отображением изображений по мере их загрузки:

// Материал, который нужно сделать один раз при загрузке $ (window) .one ("load", function () {// alert ("почему это работает, еслиЯ включаю предупреждение здесь? ");

// If the content of the scrolling area is not loaded through ajax,
// we assume it's already there and can run the code to calculate
// the width of the scrolling area, resize it to that width
if(options.ajaxContentURL.length === 0) {
 $mom.scrollableAreaWidth = 0;
 $mom.tempStartingPosition = 0;

 $mom.find(options.scrollableArea).children().find("img").each(function() {

  // Check to see if the current element in the loop is the one where the scrolling should start
  if( (options.startAtElementId.length !== 0) && (($(this).attr("id")) == options.startAtElementId) ) {
  $mom.tempStartingPosition = $mom.scrollableAreaWidth;
  }

  // Add the width of the current element in the loop to the total width
  $mom.scrollableAreaWidth = $mom.scrollableAreaWidth + $(this).outerWidth(true);
 });

 // Set the width of the scrollableArea to the accumulated width
 $mom.find(options.scrollableArea).css("width", $mom.scrollableAreaWidth + "px");

 // Check to see if the whole thing should be hidden at start
 if(options.hiddenOnStart) {
  $mom.hide();
 }
}

// Set the starting position of the scrollable area. If no startAtElementId is set, the starting position
// will be the default value (zero)
$mom.find(options.scrollWrapper).scrollLeft($mom.tempStartingPosition);

// If the user has set the option autoScroll, the scollable area will
// start scrolling automatically
if(options.autoScroll !== "") {
 $mom.autoScrollInterval = setInterval(autoScroll, $mom.autoScrollDelay);
}

// If autoScroll is set to always, the hot spots should be disabled
if(options.autoScroll == "always")
{
 hideLeftHotSpot();
 hideRightHotSpot();
}

// If the user wants to have visible hot spots, here is where it's taken care of
switch(options.visibleHotSpots)
{
 case "always":
  makeHotSpotBackgroundsVisible();
  break;
 case "onstart":
  makeHotSpotBackgroundsVisible();
  $mom.hideHotSpotBackgroundsInterval = setInterval(hideHotSpotBackgrounds, (options.hotSpotsVisibleTime * 1000));
  break;
 default:
  break; 
}

});

Полный код на http://chereecheree.com/dagworthy/style.html

Вы заметите, что если вы перезагрузитестраницы, она работает, как и ожидалось, но если вы переходите по ссылке на один уровень вверх (dagwothy /), загружается только первое изображение, если толькоВыражение lert добавляется при загрузке.

Спасибо, что нашли время, чтобы разобраться в этом!--Daniel.

1 Ответ

3 голосов
/ 01 июля 2010

Я думаю, что ваша проблема здесь, или, по крайней мере, первая, которую я вижу:

oImage = new Image();
$(oImage).load(function(){
  imageLoaded(this.src);
}).attr("src", locData.images[j].src);

if (oImage.complete && oImage.naturalWidth !== 0){
  $(this).trigger("load");
}

В этом контексте this не oImage (как это было бы в .each()), это документ , поэтому вы запускаете load не на том элементе, вам нужно иметь $(oImage).trigger("load") или $(oImage).load() вместо.

Случай, который вы пытаетесь обработать, запускать load вручную, потому что не все браузеры запускают его при загрузке изображения из кэша - правильная идея ... вам просто нужно запуститьсобытие в правом элементе, в противном случае это условие никогда не выполняется, потому что на всех этих изображениях никогда не было события load для увеличения счетчика:

if (aImagesLoaded[locId]==aImagesCount[locId]){

* alert() дает изображениям времязагрузить, так что все готово, прежде чем что-либо еще продолжится ... что само по себе выбрасывает любые условия гонки, которые у вас есть, поэтому, когда это происходит, обычно либо а) загружается некоторая зависимость, которая не успела раньше, либо б) некоторыепорядок событий сбрасывается, давая первый раз для загрузки... что, как правило, тоже отчасти а.

...