Estou escrevendo algum Javascript para redimensionar a imagem grande para caber na janela do navegador do usuário. (Não controlo o tamanho das imagens de origem, infelizmente.)
Portanto, algo assim estaria no HTML:
<img id="photo"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Existe uma maneira de determinar se a src
imagem em uma img
tag foi baixada?
Eu preciso disso porque estou tendo um problema se $(document).ready()
for executado antes que o navegador carregue a imagem. $("#photo").width()
e $("#photo").height()
retornará o tamanho do espaço reservado (o texto alternativo). No meu caso, é algo como 134 x 20.
No momento, estou apenas verificando se a altura da foto é inferior a 150 e presumindo que, se for, é apenas texto alternativo. Mas isso é um grande hack, e seria quebrado se uma foto tivesse menos de 150 pixels de altura (provavelmente não no meu caso em particular) ou se o texto alternativo tivesse mais de 150 pixels de altura (possivelmente poderia acontecer em uma pequena janela do navegador) .
Edit: Para quem deseja ver o código:
$(function()
{
var REAL_WIDTH = $("#photo").width();
var REAL_HEIGHT = $("#photo").height();
$(window).resize(adjust_photo_size);
adjust_photo_size();
function adjust_photo_size()
{
if(REAL_HEIGHT < 150)
{
REAL_WIDTH = $("#photo").width();
REAL_HEIGHT = $("#photo").height();
if(REAL_HEIGHT < 150)
{
//image not loaded.. try again in a quarter-second
setTimeout(adjust_photo_size, 250);
return;
}
}
var new_width = . . . ;
var new_height = . . . ;
$("#photo").width(Math.round(new_width));
$("#photo").height(Math.round(new_height));
}
});
Atualização : Obrigado pelas sugestões. Há o risco de o evento não ser disparado se eu definir um retorno de chamada para o $("#photo").load
evento, portanto, defini um evento onLoad diretamente na tag da imagem. Para registro, aqui está o código que acabei usando:
<img id="photo"
onload="photoLoaded();"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Depois, em Javascript:
//This must be outside $() because it may get called first
var isPhotoLoaded = false;
function photoLoaded()
{
isPhotoLoaded = true;
}
$(function()
{
//Hides scrollbars, so we can resize properly. Set with JS instead of
// CSS so that page doesn't break with JS disabled.
$("body").css("overflow", "hidden");
var REAL_WIDTH = -1;
var REAL_HEIGHT = -1;
$(window).resize(adjust_photo_size);
adjust_photo_size();
function adjust_photo_size()
{
if(!isPhotoLoaded)
{
//image not loaded.. try again in a quarter-second
setTimeout(adjust_photo_size, 250);
return;
}
else if(REAL_WIDTH < 0)
{
//first time in this function since photo loaded
REAL_WIDTH = $("#photo").width();
REAL_HEIGHT = $("#photo").height();
}
var new_width = . . . ;
var new_height = . . . ;
$("#photo").width(Math.round(new_width));
$("#photo").height(Math.round(new_height));
}
});
fonte
max-width
emax-height
estilizar as imagens com Javascript? Em seguida, você evita TODO o código que precisa escrever, definindo a largura / altura máxima para o tamanho da largura / altura da janela de visualização.max-width
emax-height
redimensionar. Mas isso é uma tarefa bastante fácil, um uso de uma linha,.resize()
na verdade.Respostas:
Adicione um ouvinte de evento ou faça com que a imagem se anuncie com onload. Em seguida, descubra as dimensões a partir daí.
<img id="photo" onload='loaded(this.id)' src="a_really_big_file.jpg" alt="this is some alt text" title="this is some title text" />
fonte
Usando o armazenamento de dados jquery, você pode definir um estado 'carregado'.
<img id="myimage" onload="$(this).data('loaded', 'loaded');" src="lolcats.jpg" />
Então, em outro lugar, você pode fazer:
if ($('#myimage').data('loaded')) { // loaded, so do stuff }
fonte
jQuery(this)
vez de$(this)
para melhor compatibilidade com outras bibliotecas (jquery não possui o $), especialmente quando você tem JavaScript em html.A resposta certa é usar event.special.load
De acordo com a documentação em .load ()
fonte
$.ready
faz. Eu ia sugerir apenas verificar a largura, mas isso tem seus problemas, eu gosto muito dessa solução.Você quer fazer o que Allain disse, no entanto, esteja ciente de que às vezes a imagem carrega antes do dom estar pronto, o que significa que seu gerenciador de carga não disparará. A melhor maneira é fazer o que Allain diz, mas defina o src da imagem com javascript após anexar o gerenciador de carregamento. Assim você garante que ele dispara.
Em termos de acessibilidade, seu site ainda funcionará para pessoas sem javascript? Você pode querer dar à tag img o src correto, anexar seu manipulador de dom ready para executar seu js: limpe o src da imagem (dê a ele um valor fixo com e altura com css para evitar a oscilação da página), em seguida, defina seu manipulador de carregamento de img, em seguida, reconfigure o src para o arquivo correto. Desta forma, você cobre todas as bases :)
fonte
De acordo com um dos comentários recentes à sua pergunta original
$(function() { $(window).resize(adjust_photo_size); adjust_photo_size(); function adjust_photo_size() { if (!$("#photo").get(0).complete) { $("#photo").load(function() { adjust_photo_size(); }); } else { ... } });
Aviso Esta resposta pode causar um loop sério no ie8 e inferior, porque img.complete nem sempre é configurado corretamente pelo navegador. Se você deve suportar o ie8, use um sinalizador para lembrar que a imagem foi carregada.
fonte
Experimente algo como:
$("#photo").load(function() { alert("Hello from Image"); });
fonte
Há um plugin jQuery chamado "imagesLoaded" que fornece um método compatível com vários navegadores para verificar se as imagens de um elemento foram carregadas.
Local: https://github.com/desandro/imagesloaded/
Uso para um contêiner que contém muitas imagens:
$('container').imagesLoaded(function(){ console.log("I loaded!"); })
O plugin é ótimo:
fonte
Algum comentário sobre este?
...
doShow = function(){ if($('#img_id').attr('complete')){ alert('Image is loaded!'); } else { window.setTimeout('doShow()',100); } }; $('#img_id').attr('src','image.jpg'); doShow();
...
Parece que funciona em qualquer lugar ...
fonte
setTimeout
Acabei de criar uma função jQuery para carregar uma imagem usando o objeto jQuerys Deferred, o que torna muito fácil reagir no evento de carregamento / erro:
$.fn.extend({ loadImg: function(url, timeout) { // init deferred object var defer = $.Deferred(), $img = this, img = $img.get(0), timer = null; // define load and error events BEFORE setting the src // otherwise IE might fire the event before listening to it $img.load(function(e) { var that = this; // defer this check in order to let IE catch the right image size window.setTimeout(function() { // make sure the width and height are > 0 ((that.width > 0 && that.height > 0) ? defer.resolveWith : defer.rejectWith)($img); }, 1); }).error(function(e) { defer.rejectWith($img); }); // start loading the image img.src = url; // check if it's already in the cache if (img.complete) { defer.resolveWith($img); } else if (0 !== timeout) { // add a timeout, by default 15 seconds timer = window.setTimeout(function() { defer.rejectWith($img); }, timeout || 15000); } // return the promise of the deferred object return defer.promise().always(function() { // stop the timeout timer window.clearTimeout(timer); timer = null; // unbind the load and error event this.off("load error"); }); } });
Uso:
var image = $('<img />').loadImg('http://www.google.com/intl/en_com/images/srpr/logo3w.png') .done(function() { alert('image loaded'); $('body').append(this); }).fail(function(){ alert('image failed'); });
Veja-o funcionando em: http://jsfiddle.net/roberkules/AdWZj/
fonte
error
evento que é controlado por.error(function(e) { defer.rejectWith($img); })
. Se você olhar para o jsFiddle, verá que ohttp://www.google.com/abc.png not found
texto é mostrado imediatamente no painel de resultados (sem esperar pelo tempo limite, porque o evento de erro começou)file://
restrição - nunca precisei vincular imagens usando o protocolo de arquivo e não acho que haja muita necessidade.Esta função verifica se uma imagem é carregada com base nas dimensões mensuráveis. Essa técnica é útil se o seu script estiver sendo executado depois que algumas das imagens já tiverem sido carregadas.
imageLoaded = function(node) { var w = 'undefined' != typeof node.clientWidth ? node.clientWidth : node.offsetWidth; var h = 'undefined' != typeof node.clientHeight ? node.clientHeight : node.offsetHeight; return w+h > 0 ? true : false; };
fonte
Eu achei que funcionou para mim
document.querySelector("img").addEventListener("load", function() { alert('onload!'); });
O crédito vai totalmente para Frank Schwieterman, que comentou sobre a resposta aceita. Tive que colocar isso aqui, é muito valioso ...
fonte
Desenvolvemos uma página onde carregava uma série de imagens e realizava outras funções somente após o carregamento da imagem. Era um site movimentado que gerava muito tráfego. Parece que o seguinte script simples funcionou em praticamente todos os navegadores:
$(elem).onload = function() { doSomething(); }
MAS ESTA É UMA QUESTÃO POTENCIAL PARA O IE9!
O ÚNICO navegador em que relatamos problemas é o IE9. Não estamos surpresos? Parece que a melhor maneira de resolver o problema é não atribuir um src à imagem até DEPOIS que a função onload tenha sido definida, assim:
$(elem).onload = function() { doSomething(); } $(elem).attr('src','theimage.png');
Parece que o IE 9 às vezes não joga o
onload
evento por qualquer motivo. Outras soluções nesta página (como a de Evan Carroll, por exemplo) ainda não funcionaram. Logicamente, isso verificou se o estado de carregamento já foi bem-sucedido e acionou a função e, se não foi, defina o manipulador onload, mas mesmo quando você fez isso, demonstramos no teste que a imagem poderia carregar entre essas duas linhas de js. aparecendo não carregado na primeira linha e depois carregando antes que o manipulador onload seja definido.Descobrimos que a melhor maneira de obter o que deseja é não definir o src da imagem até que você defina o
onload
acionador de evento.Recentemente, paramos de oferecer suporte ao IE8, então não posso falar em versões anteriores ao IE9, caso contrário, de todos os outros navegadores que foram usados no site - IE10 e 11, bem como Firefox, Chrome, Opera, Safari e outros o navegador móvel que as pessoas estavam usando - definir o
src
antes de atribuir oonload
manipulador nem mesmo era um problema.fonte
Posso sugerir uma solução totalmente CSS pura?
Basta ter um Div no qual deseja mostrar a imagem. Defina a imagem como plano de fundo. Então tenha o imóvel
background-size: cover
oubackground-size: contain
dependendo de como você quiser.cover
cortará a imagem até que os lados menores cubram a caixa.contain
irá manter a imagem inteira dentro da div, deixando você com espaços nas laterais.Verifique o snippet abaixo.
div { height: 300px; width: 300px; border: 3px dashed grey; background-position: center; background-repeat: no-repeat; } .cover-image { background-size: cover; } .contain-image { background-size: contain; }
<div class="cover-image" style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)"> </div> <br/> <div class="contain-image" style="background-image:url(https://assets1.ignimgs.com/2019/04/25/avengers-endgame-1280y-1556226255823_1280w.jpg)"> </div>
fonte
Acho que esta solução simples funciona melhor para mim:
function setEqualHeight(a, b) { if (!$(a).height()) { return window.setTimeout(function(){ setEqualHeight(a, b); }, 1000); } $(b).height($(a).height()); } $(document).ready(function() { setEqualHeight('#image', '#description'); $(window).resize(function(){setEqualHeight('#image', '#description')}); }); </script>
fonte