Асинхронная загрузка изображений с помощью jQuery


142

Я хочу загружать внешние изображения на мою страницу асинхронно, используя jQuery, и я попробовал следующее:

$.ajax({ 
   url: "http://somedomain.com/image.jpg", 
   timeout:5000,
   success: function() {

   },
   error: function(r,x) {

   }
});

Но это всегда возвращает ошибку, возможно ли загрузить изображение вот так?

Я пытался использовать .loadметод, и он работает, но я понятия не имею, как я могу установить время ожидания, если изображение недоступно (404). Как я могу это сделать?


Это работает для меня: stackoverflow.com/questions/6150289/…
MrRhoads

Ответы:


199

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

var img = $("<img />").attr('src', 'http://somedomain.com/image.jpg')
    .on('load', function() {
        if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
            alert('broken image!');
        } else {
            $("#something").append(img);
        }
    });

20
что делать с таймаутом и 404?
Краткое сообщение

1
как установить таймаут с этим? Я попробовал этот метод, но каким-то образом страница все еще ждет загрузки изображения.
Коротко

7
Если вы проверите временную шкалу вашего браузера, например, временную шкалу инструментов Google Chrome, вы увидите, что создание любого элемента DOM (независимо от того, присоединяете ли вы его к DOM или нет), а затем установка его источника добавляет его к загрузке текущего документа list - так что страница НЕ завершит «загрузку», пока не будет загружен созданный элемент. Ваше решение на самом деле не является асинхронным событием в том смысле, что window.load () не будет запускаться до тех пор, пока изображение не будет загружено, возможно, откладывая определенные операции paintили layoutоперации и, конечно же, задерживая любые onloadзависимости событий.
Том Ожер

2
@TomAuger: Так как мы можем сделать его действительно асинхронным? Я только что протестировал код с load (), и он НЕ асинхронный.
BasZero

2
@gidzior Это не работает в IE8, потому что вы не можете установить атрибут SRC в IE8, используя jquery. см. здесь: stackoverflow.com/questions/12107487/…
Рич

78

ЕСЛИ ДЕЙСТВИТЕЛЬНО ВАМ НУЖНО ИСПОЛЬЗОВАТЬ AJAX ...

Я натолкнулся на случаи, когда обработчики загрузки не были подходящим выбором. В моем случае при печати через javascript. Таким образом, для этого есть два варианта использования стиля AJAX:

Решение 1

Используйте данные изображения Base64 и сервис изображений REST. Если у вас есть собственный веб-сервис, вы можете добавить сценарий REST JSP / PHP, который предлагает изображения в кодировке Base64. Теперь, как это полезно? Я наткнулся на новый классный синтаксис для кодирования изображений:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhE..."/>

Таким образом, вы можете загрузить данные Image Base64 с помощью Ajax, а затем по завершении вы создадите строку данных Base64 для изображения! Безудержное веселье :). Я рекомендую использовать этот сайт http://www.freeformatter.com/base64-encoder.html для кодирования изображений.

$.ajax({ 
    url : 'BASE64_IMAGE_REST_URL', 
    processData : false,
}).always(function(b64data){
    $("#IMAGE_ID").attr("src", "data:image/png;base64,"+b64data);
});

Solution2:

Обманите браузер, чтобы использовать его кеш. Это дает вам хороший fadeIn (), когда ресурс находится в кэше браузера:

var url = 'IMAGE_URL';
$.ajax({ 
    url : url, 
    cache: true,
    processData : false,
}).always(function(){
    $("#IMAGE_ID").attr("src", url).fadeIn();
});   

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

ура, будет


1
Если текущее состояние поддержки браузера приемлемо для вас ( caniuse.com/#search=Blob ), вы можете использовать BLOB-объекты вместо URI данных. Это «чувствует себя» менее хакерским, чем использование URI-кодов данных в кодировке base64, а также менее затратно по отношению к памяти (поскольку base64 - неэффективный формат памяти), хотя последний, вероятно, не имеет большого значения в реальном мире.
Марк Эми

11

Используя jQuery, вы можете просто изменить атрибут «src» на «data-src». Изображение не будет загружено. Но местоположение хранится с тегом. Который я хотел.

<img class="loadlater" data-src="path/to/image.ext"/>

Простой фрагмент jQuery копирует data-src в src, который начнет загружать изображение, когда вам это нужно. В моем случае, когда страница закончила загрузку.

$(document).ready(function(){
    $(".loadlater").each(function(index, element){
        $(element).attr("src", $(element).attr("data-src"));
    });
});

Бьюсь об заклад, код jQuery может быть сокращен, но это понятно.


4
Совет: если вы используете data-тег, это справедливый немного легче получить доступ к ним через $(element).data('src')вместо$(element).attr('data-src')
Максим Кумпанен

На самом деле сегодня я бы больше не использовал jQuery. Но это вопрос личного вкуса, и он зависит от масштаба сайта, который вы создаете. Но горячая тема того времени - «Прогрессивные образы», ​​возможно, это то, на что стоит обратить внимание. smashingmagazine.com/2018/02/...
htho

8
$(<img />).attr('src','http://somedomain.com/image.jpg');

Должно быть лучше, чем ajax, потому что, если это галерея, и вы просматриваете список фотографий, если изображение уже находится в кеше, оно не будет отправлять другой запрос на сервер. Он будет запрашивать в случае jQuery / ajax и возвращать HTTP 304 (не изменен), а затем использовать исходное изображение из кэша, если оно уже там. Вышеуказанный метод уменьшает пустой запрос к серверу после первого цикла изображений в галерее.


4

Вы можете использовать отложенные объекты для загрузки ASYNC.

function load_img_async(source) {
    return $.Deferred (function (task) {
        var image = new Image();
        image.onload = function () {task.resolve(image);}
        image.onerror = function () {task.reject();}
        image.src=source;
    }).promise();
}

$.when(load_img_async(IMAGE_URL)).done(function (image) {
    $(#id).empty().append(image);
});

Пожалуйста, обратите внимание: image.onload должен быть перед image.src, чтобы предотвратить проблемы с кешем.


3

Если вы просто хотите установить источник изображения, вы можете использовать это.

$("img").attr('src','http://somedomain.com/image.jpg');

3

Это тоже работает ..

var image = new Image();
image.src = 'image url';
image.onload = function(e){
  // functionalities on load
}
$("#img-container").append(image);

2

AFAIK, вам нужно было бы сделать здесь функцию .load (), в отличие от .ajax (), но вы могли бы использовать jQuery setTimeout, чтобы сохранить его в рабочем состоянии (ish)

<script>
 $(document).ready(function() {
 $.ajaxSetup({
    cache: false
});
 $("#placeholder").load("PATH TO IMAGE");
   var refreshId = setInterval(function() {
      $("#placeholder").load("PATH TO IMAGE");
   }, 500);
});
</script>

2
извините, я немного неправильно понял ваш вопрос, я думал, что вы загружаете изображения, которые меняются или что-то (отсюда бит ajax)
benhowdle89

2

используйте .load для загрузки вашего изображения. Чтобы проверить, если вы получаете ошибку (скажем, 404), вы можете сделать следующее:

$("#img_id").error(function(){
  //$(this).hide();
  //alert("img not loaded");
  //some action you whant here
});

осторожно - событие .error () не сработает, когда атрибут src для изображения пуст.


0

$ (function () {

    if ($('#hdnFromGLMS')[0].value == 'MB9262') {
        $('.clr').append('<img src="~/Images/CDAB_london.jpg">');
    }
    else
    {
        $('.clr').css("display", "none");
        $('#imgIreland').css("display", "block");
        $('.clrIrland').append('<img src="~/Images/Ireland-v1.jpg">');
    }
});

Он работает идеально, при загрузке домашней страницы мы можем установить различные изображения - от Polaris
MadhaviLatha Bathini

Слишком много беспорядка, не связанного с ответом на вопрос.
Максим Кумпан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.