Carregar imagens de forma assíncrona com jQuery

142

Desejo carregar imagens externas em minha página de forma assíncrona usando jQuery e tentei o seguinte:

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

   },
   error: function(r,x) {

   }
});

Mas sempre retorna erro, é possível carregar uma imagem assim?

Tentei usar o .loadmétodo e ele funciona, mas não tenho idéia de como definir o tempo limite se a imagem não estiver disponível (404). Como posso fazer isso?

Arief
fonte
Isso funciona para mim: stackoverflow.com/questions/6150289/…
MrRhoads

Respostas:

199

Não há necessidade de ajax. Você pode criar um novo elemento de imagem, definir seu atributo de origem e colocá-lo em algum lugar do documento após concluir o carregamento:

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);
        }
    });
karim79
fonte
20
o que fazer com o tempo limite e 404?
Arief
1
como definir o tempo limite com isso? Eu tentei esse método, mas de alguma forma a página ainda aguarda o carregamento da imagem.
Arief
7
Se você verificar a linha do tempo do navegador, por exemplo, a linha do tempo das ferramentas de desenvolvimento do Google Chrome, verá que criar qualquer elemento DOM (independentemente de anexá-lo ou não ao DOM é aparentemente irrelevante) e, em seguida, definir sua origem o adiciona à carga do documento atual lista - para que a página NÃO termine o "carregamento" até que o elemento criado seja carregado. Sua solução, na verdade, não é um evento assíncrono, no sentido de que window.load () não será acionada até que a imagem seja carregada, possivelmente adiando determinadas operações paintou layout, e certamente atrasando quaisquer onloaddependências de eventos.
Tom Auger
2
@ TomAuger: Então, como podemos torná-lo realmente assíncrono? Acabei de testar o código com load () e NÃO é assíncrono.
precisa saber é o seguinte
2
@ gidzior Não funciona no IE8 porque você não pode definir o atributo SRC no IE8 usando jquery. consulte aqui: stackoverflow.com/questions/12107487/…
Rich
78

SE VOCÊ PRECISA USAR AJAX ...

Eu vim através de casos em que os manipuladores de carga não eram a escolha certa. No meu caso, ao imprimir via javascript. Portanto, existem duas opções para usar o estilo AJAX:

Solução 1

Use os dados de imagem Base64 e um serviço de imagem REST. Se você tiver seu próprio serviço da web, poderá adicionar um script REST JSP / PHP que ofereça imagens na codificação Base64. Agora, como isso é útil? Me deparei com uma nova sintaxe legal para codificação de imagem:

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

Assim, você pode carregar os dados do Image Base64 usando o Ajax e, após a conclusão, criar a sequência de dados Base64 na imagem! Muito divertido :). Eu recomendo usar este site http://www.freeformatter.com/base64-encoder.html para codificação de imagens.

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

Solution2:

Engane o navegador para usar seu cache. Isso fornece um bom fadeIn () quando o recurso está no cache do navegador:

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

No entanto, ambos os métodos têm suas desvantagens: o primeiro funciona apenas em navegadores modernos. O segundo apresenta falhas de desempenho e depende da suposição de como o cache será usado.

Saúde, vai

mschmoock
fonte
1
Se o estado atual do suporte ao navegador for aceitável para você ( caniuse.com/#search=Blob ), você poderá usar os Blobs em vez dos URIs de dados. Isso 'parece' menos hacky do que usar URIs de dados codificados em base64 e também gasta menos memória (já que base64 não é um formato que economiza memória), embora o último provavelmente não importe a maior parte do tempo no mundo real.
Mark Amery
11

Usando o jQuery, você pode simplesmente mudar o atributo "src" para "data-src". A imagem não será carregada. Mas o local é armazenado com a tag. Que eu gosto.

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

Uma parte simples do jQuery copia o data-src para o src, que começará a carregar a imagem quando você precisar. No meu caso, quando a página terminar de carregar.

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

Aposto que o código jQuery pode ser abreviado, mas é compreensível dessa maneira.

htho
fonte
4
Dica: se você estiver usando as data-marcas, é uma feira pouco mais fácil de acessá-los via $(element).data('src')em vez de$(element).attr('data-src')
Maxim Kumpan
Hoje, na verdade, eu não usaria mais o jQuery. Mas isso é uma questão de gosto pessoal e depende da escala do site que você está construindo. Mas o tema quente da época é "Imagens progressivas", talvez seja algo para se olhar. smashingmagazine.com/2018/02/…
htho
8
$(<img />).attr('src','http://somedomain.com/image.jpg');

Deve ser melhor que o ajax, porque se for uma galeria e você estiver percorrendo uma lista de fotos, se a imagem já estiver em cache, ela não enviará outra solicitação ao servidor. Ele solicitará no caso de jQuery / ajax e retornará um HTTP 304 (Não modificado) e, em seguida, usará a imagem original do cache, se ela já estiver lá. O método acima reduz uma solicitação vazia ao servidor após o primeiro loop de imagens na galeria.

Jaseem
fonte
4

Você pode usar objetos Adiados para carregamento 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);
});

Por favor, preste atenção: o image.onload deve estar antes do image.src para evitar problemas com o cache.

phpcoding
fonte
3

Se você quiser apenas definir a fonte da imagem, pode usá-lo.

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

Isso funciona também ..

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

AFAIK, você teria que executar uma função .load () aqui, em oposição ao .ajax (), mas você poderia usar o jQuery setTimeout para mantê-lo ativo (ish)

<script>
 $(document).ready(function() {
 $.ajaxSetup({
    cache: false
});
 $("#placeholder").load("PATH TO IMAGE");
   var refreshId = setInterval(function() {
      $("#placeholder").load("PATH TO IMAGE");
   }, 500);
});
</script>
benhowdle89
fonte
2
desculpe eu mal interpretado ligeiramente o seu Q, eu pensei que você fosse carregamento de imagens que estavam mudando ou algo (daí o bit Ajax)
benhowdle89
2

use .load para carregar sua imagem. Para testar se você receber um erro (digamos 404), faça o seguinte:

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

cuidado - evento .error () não será acionado quando o atributo src estiver vazio para uma imagem.

Poelinca Dorin
fonte
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">');
    }
});
MadhaviLatha Bathini
fonte
Seu trabalho perfectely, durante o carregamento home page podemos definir diferentes imagens - de Polaris
MadhaviLatha Bathini
Muita confusão, sem relação com a resposta à pergunta.
Maxim Kumpan