Newsgroup: it.comp.lang.javascript
Titolo: preloading di immagini

Ho semi-scopiazzato questo codice da un post di Zero di ieri mi pare...
Serve per il preloading e anche per associare una className alla fine del 
load (altrimenti dava problemi con alcuni browser).
Vorrei sapere se devo temere qualcosa da questo guazzabuglio che ho fatto 
(incompatibilita' con qualche browser o altro).
Non ho potuto provare con IE6 ma solo con IE7 (beta) e Firefox (funziona con 
entrambi).
var imageCounter=0;
function loadImage(className, url) {
  var name="imageLoadedN"+(imageCounter++);
  document.open();
  var code="<img name="+name+" />";
  document.write(code);
  document.close();
  var image = new Image();
  image.onload=function(){
    var img=document.images[name];
    img.src=url;
    img.className=className;
  }
  image.src=url;
}
viene richiamata tramite:
loadImage('imageClassExpr', '/archery/servlet-image?code=10650');
dove imageClassExpr e':
.imageClassExpr {
    max-width:90px;
    max-height:200px;
    width:expression( Math.min( parseInt(this.offsetWidth), 90 )+"px");
    height:expression( Math.min( parseInt(this.offsetHeight), 200 )+"px");
    border:0px;
}

 con entrambi).
anzi neanche con IE7.
Le immagini escono una volta si una volta no.
Con Firefox sempre ok...come mai? 

 }
Inserendo la gestione dell'altezza minima e massima nell'onload.
-- 
- Lei ha precedenti di pazzia in famiglia?
- Mio nonno credeva d' essere San Giuseppe...
- Io ci metterei un bel SI!

 }
Inserendo la gestione dell'altezza/larghezza massima nell'onload.



Ok scelgo questa tua soluzione, pero':
<img onload="loadImage(this, "image?code=214");"/>
ho provato ma non parte onload perche' manca src.
Allora ho fatto cosi':
<img onload="loadImage(this);" src="image?code=214"/>
function loadImage(ref) {
  if(ref.width>90)
    ref.width=90;
  if(ref.height>200)
    ref.height=200;
}
Pero' innanzitutto anche qua c'e' un piccolo mischiamento tra comportamento 
e forma no? Infatti avevo previsto per il futuro a riscrivere le pagine in 
modo da usare il piu' possiible css cosi da poterci fare modifiche 
all'aspetto senza dover toccare le pagine.
Comunque il problema piu' grosso in realta' e' che ref puo' essere un 
immagine abbastanza grande, e mentre viene caricata viene fuori una 
schifezza perche' e' enorme rispetto alle altre. Per questo prevedevo un css 
che ne blocca grezzamente le dimensioni durante il caricamento, ma cos' 
facendo non posso conoscere i veri width e height dell'immagine, o si?
Cioe' con
<img class="preClass" onload="loadImage(this);" src="image?code=214"/>
dove preClass ha with e height fissati, ref.height e ref.width mi ritornano 
i valori impostati dal css. 

 i valori impostati dal css.
Infatti. Ma se utilizzi gli oggetti Image() per fare il caricamento, otterrai
le dimensioni effettive.
Purtroppo non conoscendo il contesto in questione ed il framework che usi,
fatico a darti un codice effettivo; posso solo fornirti spunti e suggerimenti.


 le dimensioni effettive.
(Sono sempre cicap)
Grazie mille.
Ora sono a questo punto:
....
<img class="imageClass2" id="image0_0">
<script>loadImage('image0_0', '/servlet-image?code=10650');</script>
...
Se non ho capito male questo e' il terzo modo di fare che hai proposto.
loadImage e':
function loadImage(id, src) {
  var image = new Image();
  image.onload=function() {
    var img = document.getElementById(id);
    if(image.width>90)
      image.width=90;
    if(image.height>200)
      image.height=200;
    img.width=image.width;
    img.height=image.height;
    img.src=image.src;
  }
  image.src=src;
}
Tuttavia le immagini non si caricano, e la Javascript console non
presenta problemi di alcun tipo (sono in FireFox 1.5).

 presenta problemi di alcun tipo (sono in FireFox 1.5).
Scusa avevo sbagliato una schiocchezza.
Ora con quel sistema funziona...ma per modo di dire!
Mi stanno saltando i nervi ;)....non capisco perche' generalmente il
metodo
va, ma qualche volta alcune delle immagini non vengono caricate. Se poi
riclicco sul link subito (ho un menu laterale sempre visibile) allora
me le
carica sempre tutte.
Forse sto sbagliando lato server? Le immagini vengono prodotte da una
servlet (se conosci Java ok se no fa niente):
response.setContentType("image/jpeg");
BufferedOutputStream out = new
BufferedOutputStream(response.getOutputStream());
byte by[] = new byte[32768];
int index = inputStream.read(by, 0, 32768);
while(index != -1) {
    out.write(by, 0, index);
    index = inputStream.read(by, 0, 32768);
}
out.flush();
out.close();
Boh magari non ho settato correttamente qualche header?


Scusa avevo sbagliato una schiocchezza.


 Ora con quel sistema funziona...ma per modo di dire!
Scusate i continui post...volevo solo aggiungere che dopo qualche prova 
FireFox 1.5 da i problemi precedentemente citati, mentre con IE 6 nessun 
problema. 

 }
function loadImage(id,src){
	var img = new Image();
 
	img.onload = function(){
		var el = document.getElementById(id);
 
		if (this.width < el.width)
			el.width = this.width;
		if (this.height < el.height)
			el.height = this.height;
 
		el.src = this.src;
	}
 
	img.onerror = function(){
		alert("Non posso caricare:\r\n "+this.src);
	}
	img.src = src;
}
In questo modo specifica nella classe "width" e "height" normalmente (nel tuo
caso 90 e 200). Se le dimensioni reali dell'immagine sono inferiori,
modificherà quelle del tag di conseguenza. Altrimenti, le lascerà stare.
Nota: ho riscritto il codice partendo dal tuo, ma credo che sarebbe
auspicabile aggiungere alla funzione il controllo della proporzione,
altrimenti l'immagine rischia di venire deformata ( questo, ovviamente, in
ottica in cui vuoi scrivere una funzione riusabile che si adatti ad ogni caso
).
-- 
- Venimmo, vedemmo... e lo inculammo!

 ).
grazie mille!
Si hai ragione, il codice per simulare max-width del css non era quello, ma 
bisogna lavorare sulle proporzioni. 


Azz! sembra che non si possano sovrascrivere i valori del css (rimangono i 
valori della classe css insomma, anche se assegno nuove width e height 
all'immagine).

> el.width = this.width;
con:
	el.style.width = this.width + "px";
E ovviamente "height" di conseguenza.
-- 
"When you have eliminated the impossible, whatever remains,
however improbable, must be the truth."
on air ~ "Full Metal Panic Fumoffu - Sorega Aideshou"

 E ovviamente "height" di conseguenza.
Fatto ma anche abbandonato ;) .... IE6 fa le bizze, per cui sono tornato ai 
parametri nella funzione.
Con bizze intendo che impostando un className, el.width (che mi serve per 
fare dei calcoli che non ho mostrato) alcune volte ritorna 0, altre volte il 
valore corretto, in una maniera che mi sembra alquanto random.
Non volendo perdere giorni per una cosa del genere sono battuto in ritirata! 

 valore corretto, 
Allora il problema non è utilizzare lo style, nasce prima, nella condizione.
Quindi hai detto "fatto ma anche abbandonato" rispetto a utilizzare lo style,
non è per questo che IE6 fa le bizze.
Chissà, magari è perché IE non ha ancora finito di caricare la pagina e lo
becchi nel momento in cui non ha impostato il binding sul tag.
A questo punto prova a utilizzare el.offsetWidth oppure getComputedStyle (su
IE devi utilizzare la funzione che postai tempo fa su questo NG, e che ti
ripropongo qua sotto):
/* rendi IE un poco compatibile con gli standard W3C.. */
if (typeof window.getComputedStyle!="function"){
	window.getComputedStyle=function(elt,pseudoElt){
		return (elt!=null && typeof
elt.currentStyle=="object")?elt.currentStyle:null;
	}
}
L'alternativa sarebbe leggere direttamente il CSS, ma avresti problemi di
compatibilità con alcuni browser (i più vecchi e Opera, con IE e FF va tutto
bene).
-- 
- Voi chi dovreste essere? Una specie di cosmonauti?
- No disinfestatori, hanno visto uno scarafaggio al 12°
- Deve essere grosso questo scarafaggio
- Enorme, stacca le teste a morsi!


(Premetto che quanto dico ora e' inutile visto che ho (anzi 'hai' !) risolto 
con getComputedStyle...)
Secondo me non puo' essere altro che un problema di IE...oppure io che usavo 
cose poco stabili che non avrei  dovuto usare. Infatti questo e' lo spezzone 
di codice:
  var width = toLoad.width;
  var height = toLoad.height;
  alert(width + " " + height);
width e height possono stampare 0, altre volte il valore impostato nel 
class.
Le precondizioni sono che toLoad e' un riferimento a un elemento html "img" 
che ha class assegnato e  il "src" no.
Non puo' centrare che l'immagine sia caricata  o meno perche' toLoad a 
questo punto non sa niente del src che gli verra' impostato poi. Allora 
perche' a volte scrive "90 200"...mentre altre volte  "0 0"?
Almeno scrivesse sempre 0 0 sarei contento, significa che width e height 
sono a 0 finche' non viene caricata l'immagine, invece a volte riesce a 
leggere i valori del class correttamente...e' un problema di IE no?