evento jQuery para imagens carregadas

96

É possível detectar quando todas as imagens são carregadas por meio de um evento jQuery?

Idealmente, deve haver um

$(document).idle(function()
{
}

ou

$(document).contentLoaded(function()
{
}

Mas não consigo encontrar tal coisa.

Pensei em anexar um evento como este:

$(document).ready(function()
{
    var imageTotal = $('img').length;
    var imageCount = 0;        
    $('img').load(function(){if(++imageCount == imageTotal) doStuff();});
}

Mas isso vai quebrar se uma imagem não carregar? É extremamente importante que o método seja chamado e no momento certo.

Antony Carthy
fonte
9
Por que você não usa o evento onload: $ (window) .load (doStuff)? Onload irá, no entanto, esperar por outros recursos também (por exemplo, scripts, folhas de estilo e flash) e não apenas imagens, que podem ou não ser aceitáveis ​​para você.
moff
Anexar um evento de carregamento a todas as suas tags img, como você fez em seu exemplo de código, deve ser funcional. Se uma imagem falhar ao carregar, doStuff () não será chamado, mas isso parece razoável dado seu requisito de que todas as imagens sejam carregadas.
Steve Goodman
2
O método .load () está obsoleto desde o jQuery 1.8. Verifique isto: stackoverflow.com/questions/3877027/…
fiorix

Respostas:

116

De acordo com a documentação do jQuery , há uma série de ressalvas para o uso do evento load com imagens. Conforme observado em outra resposta, o plug-in ahpi.imgload.js está quebrado, mas a essência Paul Irish vinculada não é mais mantida.

De acordo com Paul Irish, o plug-in canônico para detectar eventos completos de carregamento de imagem agora está em:

https://github.com/desandro/imagesloaded

johnpolacek
fonte
4
Esta é a resposta - lida com várias imagens, imagens em cache, peculiaridades do navegador, imagens quebradas e está atual. Lindo.
Yarin
7
testei hoje. estava instalado e funcionando em 2 minutos.
CodeToad
Concordo com @Yarin, boa documentação, fácil de usar, múltiplo, em cache, quebrado e atual. Adoro.
johntrepreneur
No lado negativo, no entanto, imagesLoaded não oferece suporte ao IE7 se isso for importante para você.
johntrepreneur
1
Uma correção rápida e simples de 2 linhas para fazer o imagesLoaded funcionar no IE7 .
johntrepreneur
63

Se você deseja verificar não todas as imagens, mas uma específica (por exemplo, uma imagem que você substituiu dinamicamente após o DOM já estar completo), você pode usar isto:

$('#myImage').attr('src', 'image.jpg').on("load", function() {  
  alert('Image Loaded');  
});  
rsc
fonte
70
Cuidado, pois load()não disparará quando uma imagem já estiver carregada. Isso pode acontecer facilmente quando uma imagem está no cache do navegador do usuário. Você pode verificar se uma imagem já está carregada usando $('#myImage').prop('complete'), que retorna verdadeiro quando uma imagem é carregada.
Blaise
6
Por que isso tem tantos votos quando a) não responde sua pergunta eb) dá uma solução ruim além disso? (Meanshile, a resposta correta é de @ johnpolacek e tem 1 voto)
Yarin
5
AVISO!!!!!!!!!!!!!!! Esta não é a resposta correta. johnpolacek tem a resposta correta. Por favor, vote na resposta dele.
mrbinky3000,
4
Essas objeções não parecem mais ser relevantes, exceto em uma circunstância muito específica: Webkit quando você altera o src de uma imagem para o mesmo src de antes. Para imagens que você acabou de adicionar ao DOM, $ (...). Load () deve ser suficiente. Testado no FF e no Chrome atuais e no IE6-9: jsfiddle.net/b9chris/tXVCe/2
Chris Moschini
1
+1 Funciona bem quando (você sabe que) a imagem não está no cache do navegador.
Lode
28

Você pode usar meu plugin waitForImages para lidar com isso ...

$(document).waitForImages(function() {
   // Loaded.
});

A vantagem disso é que você pode localizá-lo em um elemento ancestral e, opcionalmente, detectar imagens referenciadas no CSS.

No entanto, esta é apenas a ponta do iceberg, verifique a documentação para obter mais funcionalidades.

alex
fonte
Oi Alex, parece promissor. Mas, como mencionado nas respostas e comentários de johnpolacek e hirisov, isso cobre o caso em que a imagem já está no cache do navegador?
SexyBeast de
Tenho um processo que cria uma imagem e a carrega dinamicamente depois que a página já foi carregada e precisava mostrar um carregador de Ajax enquanto o usuário espera. Este plugin funciona perfeitamente para esse caso de uso. Você deve chamar a função depois de definir a propriedade img src!
John Livermore
20

O uso de jQuery $ (). Load () como um manipulador de eventos IMG não é garantido. Se a imagem for carregada do cache, alguns navegadores podem não disparar o evento. No caso de versões (mais antigas?) Do Safari, se você alterou a propriedade SRC de um elemento IMG para o mesmo valor , o evento onload NÃO será disparado.

Parece que isso é reconhecido no jQuery (1.4.x) mais recente - http://api.jquery.com/load-event - para citar:

É possível que o evento de carregamento não seja disparado se a imagem for carregada do cache do navegador. Para levar em conta essa possibilidade, podemos usar um evento de carregamento especial que dispara imediatamente se a imagem estiver pronta. event.special.load está atualmente disponível como um plugin.

Agora existe um plug-in para reconhecer este caso e a propriedade "completa" do IE para os estados de carregamento do elemento IMG: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

jschrab
fonte
16

De acordo com esta resposta , você pode usar o evento de carregamento jQuery no windowobjeto em vez de document:

jQuery(window).load(function() {
    console.log("page finished loading now.");
});

Isso será acionado depois que todo o conteúdo da página for carregado. Isso difere do jQuery(document).load(...)que é acionado após o DOM terminar de carregar.

Tom
fonte
Isso é exatamente o que eu estava procurando!
Eric K de
4

O plugin imagesLoaded é o caminho a percorrer, se você precisar de uma solução para crossbrowser

 $("<img>", {src: 'image.jpg'}).imagesLoaded( function( $images, $proper, $broken ){
 if($broken.length > 0){
 //Error CallBack
 console.log('Error');
 }
 else{
 // Load CallBack
 console.log('Load');
 }
 });

Se você só precisa de um IE WorkAround, isso bastará

 var img = $("<img>", {
    error: function() {console.log('error'); },
    load: function() {console.log('load');}
    });
  img.attr('src','image.jpg');
Jaideep Singh
fonte
2

Para imagens da mesma origem, você pode usar:

$.get('http://www.your_domain.com/image.jpg', imgLoaded);

function imgLoaded(){
    console.log(this, 'loaded');
}
vsync
fonte
0
  function CheckImageLoadingState()
  {
     var counter = 0;
     var length = 0;

     jQuery('#siteContent img').each(function() 
     {
        if(jQuery(this).attr('src').match(/(gif|png|jpg|jpeg)$/))
          length++;
     });

     jQuery('#siteContent img').each(function() 
     {  
        if(jQuery(this).attr('src').match(/(gif|png|jpg|jpeg)$/))
        {
           jQuery(this).load(function() 
           {
           }).each(function() {
              if(this.complete) jQuery(this).load();
            });
        }
        jQuery(this).load(function()
        {
           counter++;
           if(counter === length) 
           {  
              //function to call when all the images have been loaded
              DisplaySiteContent();
           }
        });
     });
  }
doofer
fonte
0
$( "img.photo" ).load(function() {

    $(".parrentDiv").css('height',$("img.photo").height());
    // very simple

}); 
Erfan Safarpoor
fonte
0

Eu criei meu próprio script, porque achei muitos plug-ins bastante inchados, e eu só queria que funcionasse da maneira que eu queria. O meu verifica se cada imagem tem uma altura (altura da imagem nativa). Combinei isso com a função $ (window) .load () para contornar os problemas de armazenamento em cache.

O código comentei bastante, então deve ser interessante olhar, mesmo se você não o usar. Funciona perfeitamente para mim.

Sem mais delongas, aqui está:

script imgLoad.js

3Dom
fonte
0

Aguardando o carregamento de todas as imagens ...
Encontrei a resposta ao meu problema com o jfriend00 aqui jquery: como ouvir o evento de imagem carregada de um div de contêiner? .. e "if (this.complete)"
Esperando que tudo carregue e possivelmente algum no cache! .. e eu adicionei o evento "error" ... é robusto em todos os navegadores

$(function() { // Wait dom ready
    var $img = $('img'), // images collection
        totalImg = $img.length,
        waitImgDone = function() {
            totalImg--;
            if (!totalImg) {
                console.log($img.length+" image(s) chargée(s) !");
            }
        };
    $img.each(function() {
        if (this.complete) waitImgDone(); // already here..
        else $(this).load(waitImgDone).error(waitImgDone); // completed...
    });
});

Demo: http://jsfiddle.net/molokoloco/NWjDb/

Molokoloco
fonte