Newsgroup: it.comp.lang.javascript
Titolo: Problemi con popups

Salve a tutti,
uso spesso delle popup windows, soptattutto per mostrare delle foto.
Per far ciò uso una funzione che richiamo con:
href = javascript:zoom('foto.jpg')
all'interno di una mappa o di un tag <a>.
La funzione zoom è la seguente:
function zoom(foto){
 l = screen.width
 hh = screen.height
 coeff = l / 800 // discrimina tra risoluzione 1024x768 o 800x600
 ogg = new Image()
 ogg.src = foto
 lf = ogg.width
 hf = ogg.height
 larg = lf * coeff
 alte = hf * coeff
 s = (l-larg)/2
 t = (hh-alte)/2
 msg = open ("","foto","width=" + larg + ",height=" + alte + ",left=" + s +
",top=" + t);
 msg.document.write("<HTML><HEAD><TITLE>LE FOTO</TITLE></HEAD><body
background = \"sfondo.gif\" onblur=\"self.close();\">")
 msg.document.writeln("<div style=\"position:absolute; top:"+(alte-hf)/2+";
left:"+(larg-lf)/2+"\" >")
 msg.document.writeln("<img src='"+foto+"'>");
 msg.document.writeln("</div></BODY></HTML>");
 msg.document.close()
}
La cosa strana, forse non troppo, è che, la prima volta che si richiama una
foto, la finestra si apre nell angolo basso a destra dell schermo, con la
foto sull'angolo superiore sinistro; le volte successive, si apre
correttamente al centro. Infatti il codice risultante nella popup è il
seguente:
<HTML>
<HEAD>
 <TITLE>LE FOTO</TITLE>
</HEAD>
<body background = "sfondo.gif" onblur="self.close();">
<div style="position:absolute; top:0; left:0" >
<img src='foto.jpg'>
</div>
</BODY>
</HTML>
da cui si desume che 'lf = 0' e 'hf = 0'.
Perchè, la prima volta, la funzione non riesce a determinare larghezza ed
altezza della foto?
Le volte successive il codice risultante è corretto e la <div> diventa:
<div style="position:absolute; top:50.53999999999999;
left:65.80000000000001" > (dimensioni variabili a seconda della foto)
Esiste un modo per evitare questo inconveniente?
Grazie.
--
73 de IK2VTJ, Piero.
http://www.ardf.it
 , 
http://www.qsl.net/ik2vtj
Togli/Remove 'NONVOGLIOSPAM' dall'indirizzo/from address

 correttamente al centro.
[...]
Il problema sta nel codice che ho lasciato sopra.
Quando tu imposti la proprieta' src di un'immagine, ne forzi il caricamento
ma, alla riga successiva pretendi di rilevarne le dimensioni e l'immagine
non e' ancora stata scaricata.
Quando apri il popup la seconda volta l'immagine e' in cache e il suddetto
codice funziona al 99%.
Per risolvere devi prima di tutto far caricare completamente l'immagine e
poi eseguire altri processi. Un esempio al volo:
function apriPopUp(){var lf=obj.width, hf=obj.height; ...}
var obj = new Image();
obj.onload=apriPopUp;
obj.src="tuoPercorso";


Grazie, ma non sono sicuro d'aver capito.
Ho messo nel link il richiamo alla funzione
javascript:apriPopUp('foto.jpg')
function apriPopUp(foto){
  var obj = new Image();
  obj.src= foto;
  obj.onload=zoom(ogg);
}
function zoom(ogg){
    lf = ogg.width    // debug
    hf = ogg.height    // debug
    alert( lf + ' ' +hf)   // debug
  l = screen.width
  hh = screen.height
  coeff = l / 800
  lf = ogg.width
  hf = ogg.height
  .... etc ...
}
Funziona, ma sembra che il richiamo della 'zoom' avvenga immediatamente e
non quando ha finito di caricare la foto.
A volte, anche se l'alert mi da '0 0', nel tempo che la chiudo, il
caricamento è completato e la seconda serie di lf =, hf = riesce a calcolare
le dimensioni.
Togliendo le tre righe di debug, il problema permane(a volte).


 non quando ha finito di caricare la foto.
C'e' infatti una differenza tra il codice che hai scritto tu e quello mio di
prima: tu chiami la funzione.
Legare una funzione ad un evento e' istruire il computer su cosa fare quando
avverra' l'evento, quindi gli si assegna una funzione, non la si chiama.
Non c'e' il problema di passare l'oggetto alla funzione, perche' l'evento e'
stato scatenato dall'oggetto stesso:
function zoom(){
    var lf = this.width
    var hf = this.height
    ...
}
obj.onload=zoom;

 avverra' l'evento, quindi gli si assegna una funzione, non la si chiama.
Vero. Il problema è che con 'onload' la funzione viene richiamata quando il
download dell'imagine non è ancora terminato; almeno quasi sempre!
Ho provato ad utilizzare il tuo suggerimento modificando la funzione zoom
così:
function zoom(){
...
 lf = obj.width
 hf = obj.height
 larg = lf * coeff
 alte = hf * coeff
 s = (l-larg)/2
 t = (hh-alte)/2
 msg = open ("","foto","width=" + larg + ",height=" + alte + ",left=" + s +
",top=" + t);
.....
 msg.document.writeln("<img src='"+obj.src+"'>");
.....
}
ed il link così:
 <a href="javascript:var obj = new Image(); obj.onload = zoom();obj.src =
'foto.jpg'; ">foto</a>
In questo modo non funziona perchè la finestra si apre in posizione errata e
vuota; segno che le dimensioni non sono state rilevate.
Invertendo le istruzioni:
 <a href="javascript:var obj = new Image(); obj.src = 'foto.jpg'; obj.onload
= zoom();">foto</a>
non funziona lo stesso perchè la finestra, pur contenendo la foto, si apre
in posizione errata; anche in questo caso l'onload  ha richiamato la zoom
prima di finire il caricamento.
L'unico modo in cui funziona è così:
<SCRIPT type="text/javascript">
var obj = new Image();
obj.onload = zoom();
obj.src = 'foto.jpg';
</SCRIPT>
<a href="javascript:zoom() ">foto</a>,  cioè, facendo un preload
dell'immagine.
Il guaio è che non posso utilizzare questo sistema sia perché ho più foto
nella stessa pagina, sia perchè in alcuni casi il link è all'interno di una
<map>.
In ogni caso, 'obj' si riferirebbe sempre all'ultima foto caricata.
Avevo anche pensato all'introduzione di un ritardo, ma questo non è
quantificabile a priori e quindi non risolve.
Prima di ricorrere ad una soluzione drastica, passare cioè le dimensioni
alla zoom(prima versione) che mi comporta la modifica di non so quante
pagine e links, esiste un altro modo certo di risolvere il problema?
Grazie.


 quantificabile a priori e quindi non risolve.
Non capisco il problema: tu fai lo zoom su click dell'utente, quindi a
seconda dell'immagine cliccata la carichi, ne rilevi le dimensioni, e apri
di conseguenza la finestra. Poi l'immagine e' in cache e siamo tranquilli
per l'accesso successivo.
Ad ogni modo il mio consiglio e' creare le thumbnail ridotte in proporzione
rispetto all'immagine ingrandita: cosi' sai a priori e a prescindere come
aprire la finestra e non ci sono ritardi per l'utente.

 obj.src="tuoPercorso";
Ah! Ora vedo la differenza!
Comunque... grazie, ma non funziona lo stesso. :-(


 Comunque... grazie, ma non funziona lo stesso. :-(
Cosa non funziona?
Fammi vedere il codice finale che hai scritto.


Eccolo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
 <title>Untitled</title>
 <script type="text/javascript">
function zoom(){
 l = screen.width
 hh = screen.height
 coeff = l / 800
 lf = obj.width
 hf = obj.height
 larg = lf * coeff
 alte = hf * coeff
 s = (l-larg)/2
 t = (hh-alte)/2
 msg = open ("","foto","width=" + larg + ",height=" + alte + ",left=" + s +
",top=" + t);
 msg.document.write("<HTML><HEAD><TITLE>LE FOTO</TITLE></HEAD><body
background = \"immagini/ardf2.gif\" onblur=\"self.close();\">")
 msg.document.writeln("<div style=\"position:absolute; top:"+(alte-hf)/2+";
left:"+(larg-lf)/2+"\" >")
 msg.document.writeln("<img src='"+obj.src+"'>");
 msg.document.writeln("</div></BODY></HTML>");
 msg.document.close()
}
 </script>
</head>
<body>
pagina vuota<br>
<a href="javascript:var obj = new Image(); obj.onload = zoom;
obj.src='foto.jpg';">foto</a>
</body>
</html>
Nella pagina principale appare:
pagina vuota
foto
Quando si clicca su foto, la pagina principale viene sostituita
da un'altra contenente solo la scritta:
foto.jpg (tutto il codice sopra sparisce).
La popup si apre solo saltuariamente, al centro, ma mai al primo click.
SO: win2k, browser: IE 5.5.


 SO: win2k, browser: IE 5.5.
Poche modifiche.
Prima due consigli:
- le variabili dichiarale! La dichiarazione ne stabilisce anche l'area di
validita'.
- all'interno della funzione zoom, come dicevo qualche post fa, puoi
riferirti all'immagine con la parola chiave "this". Avendo tu assegnato la
funzione al gestore di eventi, e' l'oggetto stesso a chiamarla. Il vantaggio
e' che puoi modificare il resto del codice a piacimento e la funzione zoom
si riferira' sempre all'immagine che ha scatenato l'evento. Quindi:
this.width ... this.height ... this.src ...
Per il resto non sbattere tutta quella pappardella nell'attributo href. Fai
una cosa del genere:
function prontiPartenzaVia(filePath){var obj = new Image(); obj.onload =
zoom;obj.src=filePath}
<a href="foto.jpg" target="_blank"
onclick="prontiPartenzaVia(this.href);return false;">Zoom</a>
In questa maniera al click sul link viene chiamata la funzione
prontiPartenzaVia che istanzia l'immagine e fa partire il resto del
processo. Il return false impedisce l'esecuzione di href che rimane comunque
disponibile con il percorso della foto (e un target blank) per chi ha
javascript disattivato.
Dichiarando la variabile obj come interna alla funzione si pretende che tu
segua il consiglio su "this" di cui sopra, altrimenti dichiarala come
globale.


.....
Ahhh! Ora, sě! Finalmente, sembra funzionare.
Grazie di tutto!
