evento image.onload e cache do navegador

112

Desejo criar uma caixa de alerta depois que uma imagem for carregada, mas se a imagem for salva no cache do navegador, o .onloadevento não será disparado.

Como faço para disparar um alerta quando uma imagem é carregada, independentemente de a imagem ter sido armazenada em cache ou não?

var img = new Image();
img.src = "img.jpg";
img.onload = function () {
   alert("image is loaded");
}
Oto Shavadze
fonte
6
possível duplicata do callback
Fabrício Matté

Respostas:

152

Conforme você está gerando a imagem dinamicamente, defina a onloadpropriedade antes de src.

var img = new Image();
img.onload = function () {
   alert("image is loaded");
}
img.src = "img.jpg";

Fiddle - testado nas últimas versões do Firefox e Chrome.

Você também pode usar a resposta desta postagem , que adaptei para uma única imagem gerada dinamicamente:

var img = new Image();
// 'load' event
$(img).on('load', function() {
  alert("image is loaded");
});
img.src = "img.jpg";

Violino

Fabrício Matté
fonte
Esperar. Por que seu segundo exemplo de código faz a coisa errada e define .srcantes de definir .onload? Você acertou no primeiro exemplo de código, mas bagunçou o segundo. O segundo não funcionará corretamente em algumas versões do IE.
jfriend00
1
@ jfriend00 Não, não é uma bagunça. O código de backup (2º) é exatamente para caso o primeiro de alguma forma pare de funcionar. =]Ele utiliza uma .completeverificação caso a imagem já tenha sido armazenada em cache, portanto o código estava demonstrando isso. Obviamente, como prática recomendada, você sempre pode definir a srcligação after all handlers.
Fabrício Matté
4
Simplesmente NÃO há motivo para confiar .completeneste caso. Apenas configure seu gerenciador de carga antes de configurar .srce NUNCA é necessário. Eu escrevi uma apresentação de slides que é usada por milhares de sites em todos os navegadores imagináveis ​​e a primeira técnica funciona sempre. Não há necessidade de verificar .completequando criar uma nova imagem do zero como esta.
jfriend00
Tudo bem, obrigado pelo aviso, atualizei a resposta para refletir seu raciocínio =]. Além disso, @ jfriend00 você poderia verificar se a imagem carrega no IE? Me perguntando se é um problema com minha rede ou com o IE e a imagem.
Fabrício Matté 10/09/12
9
Também hoje descobri que o webkit precisa img.src = ''antes de atribuir um novo src se ele foi usado antes.
quux
10

Se o src já estiver definido, o evento será disparado no caso em cache antes mesmo de você vincular o manipulador de eventos. Portanto, você deve acionar o evento com base .completetambém.

amostra de código:

$("img").one("load", function() {
   //do stuff
}).each(function() {
   if(this.complete || /*for IE 10-*/ $(this).height() > 0)
     $(this).load();
});
Tom Sarduy
fonte
6

Existem duas soluções possíveis para esse tipo de situação:

  1. Use a solução sugerida nesta postagem
  2. Adicione um sufixo exclusivo à imagem srcpara forçar o download do navegador novamente, como este:

    var img = new Image();
    img.src = "img.jpg?_="+(new Date().getTime());
    img.onload = function () {
        alert("image is loaded");
    }

Neste código, toda vez que adicionar o carimbo de data / hora atual ao final do URL da imagem, você o torna único e o navegador irá baixar a imagem novamente

Haynar
fonte
44
Tudo o que isso faz é anular o cache. É a maneira ERRADA de resolver esse problema. O caminho certo está na resposta de Fabricio. Basta definir o .onloadmanipulador antes de definir o .srcvalor e você não perderá o evento onload em algumas versões do IE.
jfriend00
1
sim, você está certo, mas nem sempre é desejável armazenar em cache, às vezes as imagens não devem ser armazenadas em cache. é claro que nesta situação particular depende das necessidades
haynar
1
No meu aplicativo angular, tentei tudo o que outras respostas dizem, mas não ajudou. Mas forçar a não armazenar em cache como esta resposta diz funcionou para mim. Então, mais um de mim.
Thanu
A única solução que funcionou para mim na versão mais recente do Chrome.
Young Bob
3

Eu encontrei o mesmo problema hoje. Depois de tentar vários métodos, percebi que apenas colocar o código de dimensionamento dentro em $(window).load(function() {})vez de document.readyresolveria parte do problema (se você não estiver fazendo o ajax da página).

user9319
fonte
Esta também é uma boa resposta para a situação em que o navegador tem imagens em cache e funciona bem com o carregamento da janela
Shocker
exatamente o problema que eu estava enfrentando. mudar $(document).readypara $(window).loadresolveu meu problema.
Tariqul Islam
0

Descobri que você pode simplesmente fazer isso no Chrome:

  $('.onload-fadein').each(function (k, v) {
    v.onload = function () {
        $(this).animate({opacity: 1}, 2000);
    };
    v.src = v.src;
});

Definir o .src como ele mesmo acionará o evento onload.

Noah Ellman
fonte