Асинхронная загрузка изображений с помощью 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.