
Originariamente inviata da
magic_key
Ciao, carico una pagina php con il seguente codice. La pagina da caricare è piena di immagini e vorrei mostrarla solo quando tutte le immagini sono pronte. Come fare?
codice:
$('.select').change(function(){
$.ajax({
type: "POST",
url: "load.php",
data: {p: p},
dataType: "html",
success: function(msg){
$("#dest").html(msg);
}
});
}).change();
Ciao,
non so se esista un modo più "veloce" per farlo (javascript non è il mio forte, mi occupo d'altro in prevalenza), ma ad occhio direi che devi estrappolare le immagini e caricarle a mano, e quando hai terminato rendi visibile il tutto.
In pratica una cosa del genere:
codice:
$.fn.attendiImmagini = function () {
var immagini = this.find('img[src!=""]');
if (!immagini.length) {
return $.Deferred().resolve().promise();
}
var defArr = [];
var count = 0;
immagini.each(function () {
var def = $.Deferred();
count = count + 1;
def.notify(immagini.length+1);
defArr.push(def);
var immagine = new Image();
immagine.src = this.src;
immagine.onload = function () {
def.notify(immagini.length + 1);
def.resolve();
}
immagine.onerror = immagine.onload;
});
return $.when.apply($, defArr);
}
In pratica non faccio altro che recuperare le immagini contenute nel tag img (src), e per ognuna di esse mando il numero totale di immagini tramite notify (che chiamerà il progress). Inoltre aggiungo un handler per conoscere il momento in cui il caricamento dell'immagine è terminato.
Una volta che il caricamento delle immagini è terminato posso rendere visibile la pagina.
Lo usi in questo modo:
codice:
$.ajax({
url: 'pagina.html',
dataType: 'text',
success: function (response) {
$('#Pagina').html(response)
.attendiImmagini()
.progress(function (stato) {
//imposto il valore della progress bar per ogni immagine caricata
var progress = document.getElementById("progress");
if (progress.value == stato - 1)
{
//alla fine nascondo la progress bar e la riporto a 0
progress.style.visibility = "hidden";
progress.value = 0;
}
else
progress.style.visibility = "visible";
//imposto il valore massimo ed incremento il valore
progress.max = stato;
progress.value = progress.value + 1;
})
.done(function () {
//quando ha terminato il caricamento di tutte le immagini
$("#Pagina").css("visibility", "visible");
$("#link").css("visibility", "hidden");
})
.fail(function () {
//in caso di errore
});
}
});
qui un esempio funzionante, anche se la pagina la carico da una stringa, ma è lo stesso che caricarla con ajax.
p.s.
per completezza posto l'esempio completo:
codice:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<meta charset="utf-8" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
<form id="form1">
<a onclick="load();" id="link">Carica pagina</a>
<progress id="progress" style="visibility:hidden;"></progress>
<div id="Pagina" style="visibility:hidden;">
</div>
</form>
<script>
function load() {
$.ajax({ url: 'pagina.html',
dataType: 'text',
success: function (response) {
$('#Pagina').html(response)
.attendiImmagini()
.progress(function (stato) {
var progress = document.getElementById("progress");
if (progress.value == stato - 1)
{
progress.style.visibility = "hidden";
progress.value = 0;
}
else
progress.style.visibility = "visible";
progress.max = stato;
progress.value = progress.value + 1;
})
.done(function () {
$("#Pagina").css("visibility", "visible");
$("#link").css("visibility", "hidden");
})
.fail(function () {
});
}
});
}
$.fn.attendiImmagini = function () {
var immagini = this.find('img[src!=""]');
if (!immagini.length) {
return $.Deferred().resolve().promise();
}
var defArr = [];
var count = 0;
immagini.each(function () {
var def = $.Deferred();
count = count + 1;
def.notify(immagini.length+1);
defArr.push(def);
var immagine = new Image();
immagine.src = this.src;
immagine.onload = function () {
def.notify(immagini.length + 1);
def.resolve();
}
immagine.onerror = immagine.onload;
});
return $.when.apply($, defArr);
}
</script>
</body>
</html>