Возврат из JQuery get, когда все изображения загружены

Я использую jquery get для загрузки html в свой контент div. HTML-код, который я загружаю, содержит некоторые изображения, и я обнаружил, что мой собственный расчет высоты, который я выполняю в javascript, работает не слишком хорошо, потому что изображения полностью загружаются, когда возвращается loadHTML.

    var loadHTML = function(){
          return $.get("javascripts/templates/" + templateType + ".html", function(text) {
              $("#content").html(text);
          });
    };

Есть ли способ вернуться из loadHTML только после загрузки всех изображений? Я пытался позвонить и перезвонить load, но это не сработало

var loadHTML = function() {
    return $.get("javascripts/templates/" + templateType + ".html", function(text) {
        var content = $("#content").html(text);
        return $('img', content).load();
    })
};

Кроме того, я использую обещания Q в других частях своего приложения, поэтому можно ли с их помощью решить мою проблему.

ie. loadHTML.then(loadImages).then(doOtherStuff);


person Decrypter    schedule 12.11.2014    source источник


Ответы (2)


Вы можете попробовать использовать настраиваемый отложенный объект, как показано ниже

var loadHTML = function () {
    var deferred = $.Deferred();
    $.get("javascripts/templates/" + templateType + ".html", function (html) {
        var $html = $(html),
            $imgs = $html.find('img'),
            len = $imgs.length,
            counter = 0;
        $imgs.load(function () {
            if (++counter == len) {
                deferred.resolve();
            }
        });
        $("#content").html($html);
    });

    return deferred.promise();
};

TD

var list = [];
for (var i = 0; i < 5; i++) {
  list.push('<span><img src="//placehold.it/64&text=' + (i + 1) + '" /></span>');
}

var html = '<div>' + list.join('') + '</div>';

var loadHTML = function() {
  var deferred = $.Deferred();
  //using a timer to simulate ajax request
  setTimeout(function() {
    var $html = $(html),
      $imgs = $html.find('img'),
      len = $imgs.length,
      counter = 0;
    $imgs.load(function() {
      if (++counter == len) {
        deferred.resolve();
      }
    });
    $("#content").html($html);
  }, 500);

  return deferred.promise();
};

loadHTML().done(function() {
  $("#content").find('img').each(function() {
    $(this).after(this.complete)
  })
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="content"></div>

Демо: Fiddle
Демо: Проблема (измените размер изображения, чтобы увидеть проблему)

person Arun P Johny    schedule 12.11.2014
comment
Спасибо за ответ. Я объединил ваше решение с обещаниями Q. В конечном результате позволили сделать: loadHTML().then(loadImages).then(calcHeight); Спасибо за ваше предложение - person Decrypter; 12.11.2014

Мой другой ответ был удален, потому что он был слишком многословным.

Причина, по которой ваш код не работает, заключается в том, что вы отправляете запрос ajax на сервер, а затем немедленно возвращаетесь из функции. Страница продолжает свои сценарии и, вероятно, завершает большую часть своей работы до того, как этот запрос вернется с вашими изображениями.

Вам нужно переместить свой возврат в то место в вашей функции, которое, как вы знаете, не будет обрабатываться, пока данные не вернутся. Для этого можно использовать обещания:

 var jqxhr = $.get( "example.php", function() {
          alert( "request sent, images are loading" );
        // DON'T PUT YOUR RETURN HERE, 
        //YOU WANT TO CALL IT WHEN THE ABOVE IS DONE
        })
          .done(function() {
            alert( "the info is loaded" );
            //put your html insert here to make sure the 
            //data is fully loaded before you manipulate it
            //you could also call htmlresize here but that would be nesting. 
            //That shit gets complicated. Just call it after this function returns on success.
            return
          })
          .fail(function() {
            alert( "error" );
            // its good to handle errors
            return
          })

если вы не хотите задерживать загрузку всей страницы для загрузки некоторых изображений, вы можете делать фактические вещи, такие как изменение размера html и другой зависимый код в обратном вызове jqxhr.sucess, чтобы другой код читался во время прохождения ваших изображений. Но это сложно.

person Ucinorn    schedule 12.11.2014