Caricare le immagini in modo asincrono con jQuery


142

Voglio caricare immagini esterne sulla mia pagina in modo asincrono usando jQuery e ho provato quanto segue:

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

   },
   error: function(r,x) {

   }
});

Ma restituisce sempre errori, è anche possibile caricare un'immagine in questo modo?

Ho provato a utilizzare il .loadmetodo e funziona, ma non ho idea di come impostare il timeout se l'immagine non è disponibile (404). Come posso fare questo?


Risposte:


199

Non c'è bisogno di Ajax. È possibile creare un nuovo elemento immagine, impostare l'attributo di origine e posizionarlo da qualche parte nel documento al termine del caricamento:

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
cosa fare con il timeout e 404?
Breve

1
come impostare il timeout con questo? Ho provato questo metodo ma in qualche modo la pagina attende ancora il caricamento dell'immagine.
Breve

7
Se controlli la sequenza temporale del tuo browser, ad esempio la sequenza temporale degli strumenti di sviluppo di Google Chrome, vedrai che la creazione di qualsiasi elemento DOM (apparentemente non collegato al DOM è apparentemente irrilevante) e quindi l'impostazione della sua fonte lo aggiunge al carico del documento corrente list - quindi la pagina NON finirà il "caricamento" fino a quando non viene caricato l'elemento creato. La tua soluzione non è in realtà un evento asincrono, nel senso che window.load () non si attiverà fino a quando l'immagine non verrà caricata, eventualmente rimandando determinate operazioni painto layout, e sicuramente ritardando eventuali onloaddipendenze di eventi.
Tom Auger,

2
@ TomAuger: quindi come possiamo renderlo davvero asincrono? Ho appena testato il codice con load () e NON è asincrono.
basZero

2
@gidzior Non funziona in IE8 perché non è possibile impostare l'attributo SRC in IE8 usando jquery. fare riferimento qui: stackoverflow.com/questions/12107487/…
Rich

78

SE AVETE VERAMENTE BISOGNO DI USARE AJAX ...

Mi sono imbattuto in casi in cui i gestori di onload non erano la scelta giusta. Nel mio caso quando si stampa tramite javascript. Quindi ci sono in realtà due opzioni per usare lo stile AJAX per questo:

Soluzione 1

Utilizzare i dati di immagine Base64 e un servizio di immagine REST. Se si dispone di un proprio servizio Web, è possibile aggiungere uno script REST JSP / PHP che offre immagini con codifica Base64. Ora, come è utile? Mi sono imbattuto in una nuova sintassi interessante per la codifica delle immagini:

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

Quindi puoi caricare i dati di Image Base64 usando Ajax e, al termine, costruisci la stringa di dati Base64 sull'immagine! Gran divertimento :). Consiglio di utilizzare questo sito http://www.freeformatter.com/base64-encoder.html per la codifica delle immagini.

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

Solution2:

Ingannare il browser per utilizzare la sua cache. Questo ti dà una bella dissolvenza () quando la risorsa è nella cache del browser:

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

Tuttavia, entrambi i metodi hanno i suoi svantaggi: il primo funziona solo su browser moderni. Il secondo presenta problemi di prestazioni e si basa sul presupposto di come verrà utilizzata la cache.

salute, volontà


1
Se lo stato corrente del supporto del browser è accettabile per te ( caniuse.com/#search=Blob ), puoi utilizzare BLOB anziché URI di dati. Questo "sembra" meno confuso rispetto all'utilizzo di URI di dati con codifica base64 ed è anche meno dispendioso di memoria (poiché base64 non è un formato efficiente in termini di memoria), sebbene quest'ultimo probabilmente non contenga la maggior parte delle volte nel mondo reale.
Mark Amery,

11

Usando jQuery puoi semplicemente cambiare l'attributo "src" in "data-src". L'immagine non verrà caricata. Ma la posizione è memorizzata con il tag. Che gradisco.

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

Un semplice pezzo di jQuery copia data-src in src, che inizierà a caricare l'immagine quando ne avrai bisogno. Nel mio caso al termine del caricamento della pagina.

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

Scommetto che il codice jQuery potrebbe essere abbreviato, ma è comprensibile in questo modo.


4
Suggerimento: se si utilizzano i data-tag, è $(element).data('src')piuttosto più semplice accedervi tramite invece di$(element).attr('data-src')
Maxim Kumpan,

In realtà oggi non userei più jQuery. Ma questa è una questione di gusti personali e dipende dalle dimensioni del sito Web che stai costruendo. Ma l'argomento caldo del tempo è "Progressive Images", forse è qualcosa su cui guardare. smashingmagazine.com/2018/02/…
htho,

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

Dovrebbe essere migliore di Ajax perché se si tratta di una galleria e si scorre un elenco di immagini, se l'immagine è già nella cache, non invierà un'altra richiesta al server. Richiederà nel caso di jQuery / ajax e restituirà un HTTP 304 (non modificato) e quindi utilizzerà l'immagine originale dalla cache se è già presente. Il metodo sopra riduce una richiesta vuota al server dopo il primo ciclo di immagini nella galleria.


4

È possibile utilizzare oggetti rinviati per il caricamento 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);
});

Prestare attenzione: image.onload deve essere prima di image.src per evitare problemi con la cache.


3

Se vuoi solo impostare la fonte dell'immagine puoi usarla.

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

3

Funziona anche questo ..

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

2

AFAIK dovresti fare una funzione .load () come apposto a .ajax (), ma potresti usare jQuery setTimeout per mantenerlo attivo (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
mi spiace di aver frainteso leggermente la tua Q, pensavo stessi caricando immagini che stavano cambiando o qualcosa del genere (da qui il bit ajax)
benhowdle89

2

usa .load per caricare la tua immagine. per verificare se ricevi un errore (diciamo 404) puoi fare quanto segue:

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

attento: l'evento .error () non si attiva quando l'attributo src è vuoto per un'immagine.


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


Troppo disordine, non correlato alla risposta alla domanda.
Maxim Kumpan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.