Voglio fare:
$("img").bind('load', function() {
// do stuff
});
Ma l'evento load non si attiva quando l'immagine viene caricata dalla cache. I documenti jQuery suggeriscono un plugin per risolvere questo problema, ma non funziona
Voglio fare:
$("img").bind('load', function() {
// do stuff
});
Ma l'evento load non si attiva quando l'immagine viene caricata dalla cache. I documenti jQuery suggeriscono un plugin per risolvere questo problema, ma non funziona
Risposte:
Se l' src
opzione è già impostata, l'evento viene generato nel caso memorizzato nella cache, prima ancora di ottenere il limite del gestore eventi. Per risolvere questo problema, puoi controllare e attivare l'evento in base al ciclo .complete
, in questo modo:
$("img").one("load", function() {
// do stuff
}).each(function() {
if(this.complete) {
$(this).load(); // For jQuery < 3.0
// $(this).trigger('load'); // For jQuery >= 3.0
}
});
Nota la modifica da .bind()
a in .one()
modo che il gestore eventi non venga eseguito due volte.
setTimeout(function(){//do stuff},0)
all'interno della funzione 'load' ... lo 0 dà al sistema browser (DOM) un segno di spunta in più per garantire che tutto sia correttamente aggiornato.
.load()
non attiva l'evento e ha 1 argomento richiesto, utilizzare .trigger("load")
invece
Posso suggerire di ricaricarlo in un oggetto immagine non DOM? Se è memorizzato nella cache, non ci vorrà del tempo e l'onload verrà comunque attivato. Se non è memorizzato nella cache, genererà l'onload al caricamento dell'immagine, che dovrebbe coincidere con il completamento del caricamento della versione DOM dell'immagine.
Javascript:
$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.src = $('#img').attr('src') ;
tmpImg.onload = function() {
// Run onload code.
} ;
}) ;
Aggiornato (per gestire più immagini e con allegato di caricamento correttamente ordinato):
$(document).ready(function() {
var imageLoaded = function() {
// Run onload code.
}
$('#img').each(function() {
var tmpImg = new Image() ;
tmpImg.onload = imageLoaded ;
tmpImg.src = $(this).attr('src') ;
}) ;
}) ;
load
gestore prima che venga aggiunto, anche questo non funzionerà ma per un'immagine, il codice OP funziona per molti :)
#img
è un ID, non un selettore di elementi :) this.src
Funziona anche , non è necessario utilizzare jQuery dove non è necessario :) Ma la creazione di un'altra immagine sembra eccessiva in entrambi i casi IMO.
imageLoaded
, utilizzaretmp.onload = imageLoaded.bind(this)
La mia soluzione semplice, non ha bisogno di alcun plugin esterno e per i casi comuni dovrebbe essere sufficiente:
/**
* Trigger a callback when the selected images are loaded:
* @param {String} selector
* @param {Function} callback
*/
var onImgLoad = function(selector, callback){
$(selector).each(function(){
if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
callback.apply(this);
}
else {
$(this).on('load', function(){
callback.apply(this);
});
}
});
};
usalo così:
onImgLoad('img', function(){
// do stuff
});
ad esempio, per sbiadire le immagini al caricamento puoi fare:
$('img').hide();
onImgLoad('img', function(){
$(this).fadeIn(700);
});
O in alternativa, se preferisci un approccio simile a un plug-in jquery:
/**
* Trigger a callback when 'this' image is loaded:
* @param {Function} callback
*/
(function($){
$.fn.imgLoad = function(callback) {
return this.each(function() {
if (callback) {
if (this.complete || /*for IE 10-*/ $(this).height() > 0) {
callback.apply(this);
}
else {
$(this).on('load', function(){
callback.apply(this);
});
}
}
});
};
})(jQuery);
e usalo in questo modo:
$('img').imgLoad(function(){
// do stuff
});
per esempio:
$('img').hide().imgLoad(function(){
$(this).fadeIn(700);
});
width
, max-height
e il congedo height:auto
, spesso è necessario impostare sia la larghezza e l'altezza solo se è necessario allungare l'immagine; per una soluzione più robusta vorrei utilizzare un plugin come ImagesLoaded
Devi davvero farlo con jQuery? Puoi allegare l' onload
evento direttamente anche alla tua immagine;
<img src="/path/to/image.jpg" onload="doStuff(this);" />
Si attiverà ogni volta che l'immagine è stata caricata, dalla cache o meno.
onload
gestore si attiverà quando l'immagine viene caricata una seconda volta dalla cache?
È inoltre possibile utilizzare questo codice con supporto per errore di caricamento:
$("img").on('load', function() {
// do stuff on success
})
.on('error', function() {
// do stuff on smth wrong (error 404, etc.)
})
.each(function() {
if(this.complete) {
$(this).load();
} else if(this.error) {
$(this).error();
}
});
load
prima il gestore e poi chiamarlo successivamente nella each
funzione.
Ho avuto questo problema da solo, ho cercato ovunque una soluzione che non prevedesse l'uccisione della mia cache o il download di un plug-in.
Non ho visto subito questa discussione, quindi ho trovato qualcos'altro che è una soluzione interessante e (penso) degno di essere pubblicato qui:
$('.image').load(function(){
// stuff
}).attr('src', 'new_src');
In realtà ho avuto questa idea dai commenti qui: http://www.witheringtree.com/2009/05/image-load-event-binding-with-ie-using-jquery/
Non ho idea del perché funzioni, ma ho provato questo su IE7 e dove si è rotto prima che ora funzioni.
Spero che sia d'aiuto,
La risposta accettata in realtà spiega perché:
Se src è già impostato, l'evento viene generato nella cache inserita prima di ottenere il limite del gestore eventi.
$image.load(function(){ something(); }).attr('src', $image.attr('src'));
per ripristinare la fonte originale.
Usando jQuery per generare una nuova immagine con l'src dell'immagine e assegnando il metodo load direttamente a quello, il metodo load viene chiamato con successo quando jQuery termina di generare la nuova immagine. Questo funziona per me in IE 8, 9 e 10
$('<img />', {
"src": $("#img").attr("src")
}).load(function(){
// Do something
});
Una soluzione che ho trovato https://bugs.chromium.org/p/chromium/issues/detail?id=7731#c12 (Questo codice è stato preso direttamente dal commento)
var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;
Una modifica all'esempio di GUS:
$(document).ready(function() {
var tmpImg = new Image() ;
tmpImg.onload = function() {
// Run onload code.
} ;
tmpImg.src = $('#img').attr('src');
})
Imposta l'origine prima e dopo l'onload.
src
prima il collegamento del onload
gestore, una volta dopo sarà sufficiente.
Basta aggiungere nuovamente l'argomento src su una riga separata dopo aver definito l'img oject. Ciò indurrà IE a innescare l'evento lad. È brutto, ma è la soluzione più semplice che ho trovato finora.
jQuery('<img/>', {
src: url,
id: 'whatever'
})
.load(function() {
})
.appendTo('#someelement');
$('#whatever').attr('src', url); // trigger .load on IE
Posso darti un piccolo consiglio se vuoi fare così:
<div style="position:relative;width:100px;height:100px">
<img src="loading.jpg" style='position:absolute;width:100px;height:100px;z-index:0'/>
<img onLoad="$(this).fadeIn('normal').siblings('img').fadeOut('normal')" src="picture.jpg" style="display:none;position:absolute;width:100px;height:100px;z-index:1"/>
</div>
Se lo fai quando il browser memorizza le immagini nella cache, non è un problema mostrare sempre img ma caricando img sotto un'immagine reale.
Ho avuto questo problema con IE, dove e.target.width sarebbe indefinito. L'evento load si attiva ma non riesco a ottenere le dimensioni dell'immagine in IE (chrome + FF ha funzionato).
Si scopre che è necessario cercare e.currentTarget.naturalWidth e e.currentTarget.naturalHeight .
Ancora una volta, IE fa le cose a modo suo (più complicato).
Puoi risolvere il tuo problema usando il plugin JAIL che ti consente anche di caricare le immagini in modo pigro (migliorando le prestazioni della pagina) e passando il callback come parametro
$('img').asynchImageLoader({callback : function(){...}});
L'HTML dovrebbe apparire come
<img name="/global/images/sample1.jpg" src="/global/images/blank.gif" width="width" height="height" />
Se vuoi una soluzione CSS pura, questo trucco funziona molto bene: usa l'oggetto di trasformazione. Questo funziona anche con le immagini quando sono memorizzate nella cache o meno:
CSS:
.main_container{
position: relative;
width: 500px;
height: 300px;
background-color: #cccccc;
}
.center_horizontally{
position: absolute;
width: 100px;
height: 100px;
background-color: green;
left: 50%;
top: 0;
transform: translate(-50%,0);
}
.center_vertically{
position: absolute;
top: 50%;
left: 0;
width: 100px;
height: 100px;
background-color: blue;
transform: translate(0,-50%);
}
.center{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background-color: red;
transform: translate(-50%,-50%);
}
HTML:
<div class="main_container">
<div class="center_horizontally"></div>
<div class="center_vertically"></div>
<div class="center"></div>
</div>
</div