Асинхронно завантажуйте зображення за допомогою 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

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

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, мабуть, не має значення), а потім встановлення джерела додає його до завантаження поточного документа список - тому сторінка НЕ ​​закінчиться "завантаженням", поки цей створений елемент не буде завантажений. Ваше рішення насправді не asyncrhonous подія в тому сенсі , що 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. Якщо у вас є власна веб-служба, ви можете додати сценарій JSP / PHP REST, який пропонує зображення в кодуванні Base64. Тепер, як це корисно? Я натрапив на новий класний синтаксис кодування зображень:

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

Таким чином, ви можете завантажити дані Base64 Image за допомогою 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);
});

Рішення2:

Підманьте браузер використовувати свій кеш. Це дає вам приємне 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 ), ви можете використовувати Blobs замість 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
вибачте, я трохи не зрозумів ваш Q, я подумав, що ви завантажуєте зображення, які змінюються чи щось таке (отже, біт Ajax)
benhowdle89

2

використовувати .load для завантаження зображення. щоб перевірити, якщо ви отримали помилку (скажімо, 404), ви можете зробити наступне:

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

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


0

$ (функція () {

    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.