Estoy escribiendo algo de Javascript para cambiar el tamaño de la imagen grande para que quepa en la ventana del navegador del usuario. (Desafortunadamente, no controlo el tamaño de las imágenes de origen).
Entonces, algo como esto estaría en el HTML:
<img id="photo"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
¿Hay alguna forma de determinar si la src
imagen de una img
etiqueta se ha descargado?
Necesito esto porque tengo un problema si $(document).ready()
se ejecuta antes de que el navegador haya cargado la imagen. $("#photo").width()
y $("#photo").height()
devolverá el tamaño del marcador de posición (el texto alternativo). En mi caso, esto es algo así como 134 x 20.
En este momento, solo estoy comprobando si la altura de la foto es inferior a 150, y suponiendo que, si es así, es solo texto alternativo. Pero esto es todo un truco, y se rompería si una foto tiene menos de 150 píxeles de alto (no es probable en mi caso particular), o si el texto alternativo tiene más de 150 píxeles de alto (posiblemente podría ocurrir en una ventana pequeña del navegador) .
Editar: para cualquiera que quiera ver el 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));
}
});
Actualización : Gracias por las sugerencias. Existe el riesgo de que el evento no se active si configuro una devolución de llamada para el $("#photo").load
evento, por lo que he definido un evento onLoad directamente en la etiqueta de la imagen. Para que conste, aquí está el código con el que terminé yendo:
<img id="photo"
onload="photoLoaded();"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Luego en 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));
}
});
fuente
max-width
ymax-height
en el estilo de la imagen con Javascript? Luego, evita TODO el código que ha necesitado escribir estableciendo el ancho / alto máximo en el tamaño del ancho / alto de la ventana gráfica.max-width
ymax-height
cambiar el tamaño. Pero esa es una tarea bastante fácil, de hecho, una sola línea.resize()
.Respuestas:
Agregue un detector de eventos o haga que la imagen se anuncie con onload. Luego, calcula las dimensiones a partir de ahí.
<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" />
fuente
Usando el almacén de datos jquery puede definir un estado 'cargado'.
<img id="myimage" onload="$(this).data('loaded', 'loaded');" src="lolcats.jpg" />
Luego, en otro lugar puedes hacer:
if ($('#myimage').data('loaded')) { // loaded, so do stuff }
fuente
jQuery(this)
lugar de$(this)
para una mejor compatibilidad con otras bibliotecas (jquery no es propietario de $), especialmente cuando tiene JavaScript en html.La respuesta correcta es usar event.special.load
Según los documentos en .load ()
fuente
$.ready
hace. Iba a sugerir simplemente verificar el ancho, pero eso tiene sus problemas, realmente me gusta esa solución.Desea hacer lo que dijo Allain, sin embargo, tenga en cuenta que a veces la imagen se carga antes de que dom esté listo, lo que significa que su controlador de carga no se activará. La mejor manera es hacer lo que dice Allain, pero establecer el src de la imagen con javascript después de adjuntar el controlador de carga. De esta forma puede garantizar que se dispara.
En términos de accesibilidad, ¿su sitio seguirá funcionando para personas sin javascript? Es posible que desee darle a la etiqueta img el src correcto, adjunte su controlador dom ready para ejecutar su js: borre la imagen src (déle un valor fijo con y altura con css para evitar que la página parpadee), luego configure su controlador de carga img, luego restablezca el src al archivo correcto. De esta manera cubrirá todas las bases :)
fuente
Según uno de los comentarios recientes a su pregunta 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 { ... } });
Advertencia Esta respuesta podría causar un bucle grave en ie8 y versiones inferiores, porque img.complete no siempre está configurado correctamente por el navegador. Si debe admitir ie8, use una bandera para recordar que la imagen está cargada.
fuente
Prueba algo como:
$("#photo").load(function() { alert("Hello from Image"); });
fuente
Hay un complemento de jQuery llamado "imagesLoaded" que proporciona un método compatible con varios navegadores para verificar si se han cargado las imágenes de un elemento.
Sitio: https://github.com/desandro/imagesloaded/
Uso de un contenedor que tiene muchas imágenes en su interior:
$('container').imagesLoaded(function(){ console.log("I loaded!"); })
El complemento es genial:
fuente
¿Algún comentario 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 en todas partes ...
fuente
setTimeout
Acabo de crear una función jQuery para cargar una imagen usando jQuerys Deferred Object que hace que sea muy fácil reaccionar ante un evento de carga / error:
$.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'); });
Véalo funcionando en: http://jsfiddle.net/roberkules/AdWZj/
fuente
error
evento manejado por.error(function(e) { defer.rejectWith($img); })
. Si observa jsFiddle, verá que elhttp://www.google.com/abc.png not found
texto se muestra inmediatamente en el panel de resultados (sin esperar un tiempo de espera, porque el evento de error sefile://
restricción: nunca necesité vincular imágenes usando el protocolo de archivo y no creo que sea muy necesario.Esta función comprueba si una imagen se carga basándose en tener dimensiones medibles. Esta técnica es útil si su script se está ejecutando después de que algunas de las imágenes ya se hayan cargado.
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; };
fuente
Encontré que esto funcionó para mí
document.querySelector("img").addEventListener("load", function() { alert('onload!'); });
El crédito va totalmente a Frank Schwieterman, quien comentó la respuesta aceptada. Tuve que poner esto aquí, es demasiado valioso ...
fuente
Desarrollamos una página donde cargaba una serie de imágenes y luego realizaba otras funciones solo después de que se cargaba la imagen. Era un sitio muy concurrido que generaba mucho tráfico. Parece que el siguiente script simple funcionó en prácticamente todos los navegadores:
$(elem).onload = function() { doSomething(); }
¡PERO ESTE ES UN PROBLEMA POTENCIAL PARA IE9!
El ÚNICO navegador sobre el que informamos problemas es IE9. ¿No nos sorprende? Parece que la mejor manera de resolver el problema es no asignar un src a la imagen hasta DESPUÉS de que se haya definido la función de carga, así:
$(elem).onload = function() { doSomething(); } $(elem).attr('src','theimage.png');
Parece que IE 9 a veces no arroja el
onload
evento por cualquier motivo. Otras soluciones en esta página (como la de Evan Carroll, por ejemplo) aún no funcionaban. Lógicamente, eso verificó si el estado de carga ya fue exitoso y activó la función y, si no lo fue, luego configure el controlador de carga, pero incluso cuando lo haga, demostramos en la prueba que la imagen podría cargarse entre esas dos líneas de js, aparece no cargado en la primera línea y luego se carga antes de que se establezca el controlador de carga.Descubrimos que la mejor manera de obtener lo que desea es no definir el src de la imagen hasta que haya configurado el activador del
onload
evento.Recientemente dejamos de admitir IE8, por lo que no puedo hablar de versiones anteriores a IE9, de lo contrario, de todos los demás navegadores que se usaron en el sitio: IE10 y 11, así como Firefox, Chrome, Opera, Safari y lo que sea. Los navegadores móviles que usaban las personas: configurar el
src
antes de asignar elonload
controlador ni siquiera era un problema.fuente
¿Puedo sugerir una solución CSS pura por completo?
Solo tenga un Div en el que desee mostrar la imagen. Establezca la imagen como fondo. Entonces tienes la propiedad
background-size: cover
obackground-size: contain
según como la quieras.cover
recortará la imagen hasta que los lados más pequeños cubran la caja.contain
mantendrá la imagen completa dentro del div, dejándote con espacios en los lados.Consulte el fragmento a continuación.
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>
fuente
Encuentro que esta sencilla solución funciona mejor para mí:
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>
fuente