Asynchronicznie ładuj obrazy za pomocą jQuery


142

Chcę ładować obrazy zewnętrzne na mojej stronie asynchronicznie za pomocą jQuery i wypróbowałem następujące rozwiązania:

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

   },
   error: function(r,x) {

   }
});

Ale zawsze zwraca błąd, czy w ogóle można załadować taki obraz?

Próbowałem użyć .loadmetody i działa, ale nie mam pojęcia, jak ustawić limit czasu, jeśli obraz nie jest dostępny (404). W jaki sposób mogę to zrobić?


Odpowiedzi:


199

Nie ma potrzeby Ajax. Możesz utworzyć nowy element obrazu, ustawić jego atrybut źródłowy i umieścić go gdzieś w dokumencie po zakończeniu ładowania:

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
co zrobić z limitem czasu i 404?
Arief

1
jak ustawić z tym limit czasu? Wypróbowałem tę metodę, ale jakoś strona nadal czeka na załadowanie obrazu.
Arief

7
Jeśli sprawdzisz oś czasu swojej przeglądarki, na przykład oś czasu narzędzi programistycznych Google Chrome, zobaczysz, że utworzenie dowolnego elementu DOM (bez względu na to, czy dołączysz go do DOM, jest najwyraźniej nieistotne), a następnie ustawienie jego źródła powoduje dodanie go do ładowania bieżącego dokumentu list - tak więc strona NIE zakończy się "ładowaniem", dopóki utworzony element nie zostanie załadowany. Twoje rozwiązanie w rzeczywistości nie jest zdarzeniem asynchronicznym w tym sensie, że window.load () nie zostanie uruchomione, dopóki obraz nie zostanie załadowany, prawdopodobnie odraczając pewne operacje paintlub z layoutpewnością opóźniając wszelkie onloadzależności zdarzeń.
Tom Auger

2
@TomAuger: Jak więc możemy sprawić, by był naprawdę asynchroniczny? Właśnie przetestowałem kod za pomocą load () i NIE jest on asynchroniczny.
basZero

2
@gidzior To nie działa w IE8, ponieważ nie można ustawić atrybutu SRC w IE8 za pomocą jquery. zobacz tutaj: stackoverflow.com/questions/12107487/…
Rich

78

JEŚLI NAPRAWDĘ POTRZEBUJESZ UŻYWAĆ AJAX ...

Spotkałem się z przypadkami, w których obsługa załadunku nie była właściwym wyborem. W moim przypadku podczas drukowania za pomocą javascript. W rzeczywistości istnieją dwie opcje użycia stylu AJAX do tego:

Rozwiązanie 1

Użyj danych obrazu Base64 i usługi obrazu REST. Jeśli masz własną usługę internetową, możesz dodać skrypt JSP / PHP REST, który oferuje obrazy w kodowaniu Base64. Jak to jest przydatne? Natknąłem się na nową, fajną składnię do kodowania obrazu:

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

Możesz więc załadować dane obrazu Base64 za pomocą Ajax, a następnie po zakończeniu zbudować ciąg danych Base64 do obrazu! Świetna zabawa :). Polecam skorzystać z tej witryny http://www.freeformatter.com/base64-encoder.html do kodowania obrazu.

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

Rozwiązanie 2:

Oszukaj przeglądarkę, aby użyła jej pamięci podręcznej. Daje to przyjemną funkcję fadeIn (), gdy zasób znajduje się w pamięci podręcznej przeglądarki:

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

Jednak obie metody mają swoje wady: pierwsza działa tylko w nowoczesnych przeglądarkach. Drugi ma problemy z wydajnością i opiera się na założeniu, w jaki sposób będzie używana pamięć podręczna.

okrzyki, will


1
Jeśli aktualny stan obsługi przeglądarki jest dla Ciebie akceptowalny ( caniuse.com/#search=Blob ), możesz użyć obiektów BLOB zamiast identyfikatorów URI danych. To `` wydaje się '' mniej hakerskie niż używanie identyfikatorów URI danych zakodowanych w base64, a także mniej marnuje pamięć (ponieważ base64 nie jest formatem wydajnym pod kątem pamięci), chociaż ten ostatni prawdopodobnie nie ma znaczenia w prawdziwym świecie.
Mark Amery,

11

Używając jQuery możesz po prostu zmienić atrybut „src” na „data-src”. Obraz nie zostanie załadowany. Ale lokalizacja jest przechowywana ze znacznikiem. Które lubię.

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

Prosty fragment jQuery kopiuje data-src do src, który rozpocznie ładowanie obrazu, gdy będzie potrzebny. W moim przypadku, gdy strona się załadowała.

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

Założę się, że kod jQuery można by skrócić, ale w ten sposób jest to zrozumiałe.


4
Wskazówka: jeśli używasz data-tagów, dostęp do nich jest nieco łatwiejszy przez $(element).data('src')zamiast$(element).attr('data-src')
Maxim Kumpan

Właściwie dzisiaj nie użyłbym już jQuery. Ale to kwestia osobistego gustu i zależy od skali witryny, którą budujesz. Ale gorącym tematem tamtych czasów są „obrazy progresywne”, być może warto się temu przyjrzeć. smashingmagazine.com/2018/02/…
htho

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

Powinno być lepsze niż Ajax, ponieważ jeśli jest to galeria i przeglądasz listę zdjęć, jeśli obraz jest już w pamięci podręcznej, nie wyśle ​​kolejnego żądania do serwera. Będzie zażądać w przypadku jQuery / ajax i zwróci HTTP 304 (niezmodyfikowany), a następnie użyje oryginalnego obrazu z pamięci podręcznej, jeśli już tam jest. Powyższa metoda redukuje puste żądanie do serwera po pierwszej pętli obrazów w galerii.


4

Możesz użyć obiektów odroczonych do ładowania 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);
});

Zwróć uwagę: image.onload musi znajdować się przed image.src, aby uniknąć problemów z cache.


3

Jeśli chcesz tylko ustawić źródło obrazu, możesz tego użyć.

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

3

To też działa ...

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

2

AFAIK, musiałbyś tutaj wykonać funkcję .load () jako dołączoną do .ajax (), ale możesz użyć jQuery setTimeout, aby utrzymać ją na żywo (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
przepraszam, trochę źle zrozumiałem twój Q, myślałem, że ładujesz obrazy, które się zmieniają lub coś takiego (stąd bit
Ajax

2

użyj .load, aby załadować obraz. aby sprawdzić, czy pojawia się błąd (powiedzmy 404), możesz wykonać następujące czynności:

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

uwaga - zdarzenie .error () nie zostanie wywołane, gdy atrybut src jest pusty dla obrazu.


0

$ (funkcja () {

    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">');
    }
});


Za dużo bałaganu, niezwiązanego z odpowiedzią na pytanie.
Maxim Kumpan
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.