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' srcopzione è 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') ;
}) ;
}) ;
loadgestore 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.srcFunziona 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-heighte 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' onloadevento 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.
onloadgestore 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();
}
});
loadprima il gestore e poi chiamarlo successivamente nella eachfunzione.
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.
srcprima il collegamento del onloadgestore, 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