Newsgroup: it.comp.lang.javascript
Titolo: jquery e funzioni animate multiple

Ho un fastidioso problema nella scrittura di un codice con jquery.
Prendiamo le seguenti righe:
 
$("#Associazione").click(function () {
	$(".curiosita,.parco.storia,").animate({width: "0px", height: 
"0px"},"slow")
	$(".associazione").animate({width: "160px", height: "120px"},"slow")	
	});
 
Quando viene fatto click su Associazione (ID Associazione), questo 
codice chiude le classi curiosita, parco e storia ed apre la classe 
associazione.
E questo può essere fatto per ciascuna classe cambiando 
$("#XYZ").click(function ()
Mettiamo il caso che debba fare 40 funzioni dove mi si chiudono tutte le 
classi meno 1, come debbo fare per non scriverle tutte per ciascuna 
class che si deve aprire?
Per provare, ho messo i nomi delle classi in un array; poi tutto in una 
function dove tutte le classi, meno quella dalla function chiamante 
vengono chiuse (passo il nome della classe) ed al ritorno mi apre quella 
che ha chiamato, ma l’effetto visivo è diverso è peggiore.
Qualche consiglio?
Leonardo
 

 che ha chiamato, ma l’effetto visivo è diverso è peggiore.
 
Interessante, dovrebbe essere lo stesso. Potresti scrivere anche il
tentativo che hai fatto? Magari c'è un errore o un passaggio non ovvio
che spiega il calo di performance. A naso (e ripeto, a naso), direi che
la procedura che hai fatto va bene. Se fosse un problema di performance
dovuto all'esclusione della classe da aprire dalla lista di classi da
chiudere, si potrebbe ovviare con del caching, altrimenti a naso:
 
    var displayByClassName = function() {
        var classes = [
            ".curiosita", ".parco", ".animazione", ".storia"
        ];
 
        return function (className) {
            var classesToClose = classes.filter(function(el) {
                return el !== className;
            });
 
            $(classesToClose.join()).animate(
                {width: "0px", height: "0px"},
                "slow"
            );
 
            $(className).animate(
                {width: "160px", height: "120px"},
                "slow"
            );
        }
    }();
 
    $("#Animazione").click(function () {
        displayByClassName(".animazione");
    });
 
Scritto di getto, potrebbe contenere errori. Mi viene da chiederti,
però: se puoi avere una sola classe "aperta" alla volta, non è meglio se
ti ricordi in qualche modo (oppure usi una classe/id di appoggio) qual'è
l'elemento corrente che è aperto, e chiudi solo quello invece che tutte
le classi? C'è qualcosa che te lo impedisce?
 


Ti ringrazio della risposta.
Quella che segue è l'intera pagina web funzionante (ovviamente alle 
immagini il link appare interrotto).
Tiene presente che funziona sicuramente in FF ma non in IE.
Facendo prove e modifiche, per una ragione che ignoro, devo avere 
scritto qualcosa che non piace a IE. Ma il succo del problema non cambia.
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
">
<html xmlns="
http://www.w3.org/1999/xhtml
">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento senza titolo</title>
 
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
 
<script type="text/javascript">
 
var sezioni = new 
Array(".Associazione",".Curiosita",".Persone",".Oltreconfine",".ParcoFluviale",".Repetti",".Storia",".Territorio",".Uffizi")
 
$(document).ready(function() {
 
function Nasconde(No)
{
 
for(x=0; x < sezioni.length;x++)
{
	if(sezioni[x] != No)
	{
	$(sezioni[x]).animate({width: "0px", height: "0px"},"slow")
	}
}
}
 
 
$("#Tutti").click(function () {
 
	for(x=0; x < sezioni.length;x++)
{
	$(sezioni[x]).animate({width: "160px", height: "120px"},"slow")
}
});
 
 
$("#Associazione").click(function () {
	Nasconde(".Associazione")
	$(".Associazione").animate({width: "160px", height: "120px"},"slow")
});
 
$("#Curiosita").click(function () {
	Nasconde(".Curiosita")
	$(".Curiosita").animate({width: "160px", height: "120px"},"slow")
});
 
$("#Persone").click(function () {
	Nasconde(".Persone")
	$(".Persone").animate({width: "160px", height: "120px"},"slow")
});
 
});
</script>
 
<style type="text/css">
body {
	margin-left: 0px;
	margin-top: 0px;
	margin-right: 0px;
	margin-bottom: 0px;
}
 
#Contenitore{border:1px solid #FF0000;
	position: absolute;
	top:0px;
	left:50%;
	margin-left: -490px;
	width:980px;
	height:1578px;
	z-index: 0;
	}
 
#tabsE{border:1px solid #FFFF00; /* contiene le voci del menù */
position: absolute;
top:200px;
width: 100%;
}
 
 
#ContenitoreMiniature{border:1px solid #FFFF00;
position: absolute;
top:300px;
width: 100%;
overflow: visible;
}
 
 
.Miniature{
float: left;
}
 
 
</style>
</head>
 
<body>
 
<div id="Contenitore">
 
<div id="tabsE">
<ul>
<li><a href="#" id="Tutti"><span>Tutti</span></a></li>
<li><a href="#" id="Associazione"><span>Associazione</span></a></li>
<li><a href="#" id="Curiosita"><span>Curiosita</span></a></li>
<li><a href="#" id="Persone"><span>Persone</span></a></li>
</ul>
</div>
 
 
 
<div id="ContenitoreMiniature">
 
<div class="Miniature"><img src="img-index/img1.jpg" 
class="Associazione" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img2.jpg" class="Curiosita" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img3.jpg" class="Persone" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img4.jpg" 
class="Oltreconfine"  width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img5.jpg" 
class="ParcoFluviale" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/parcofluviale.jpg" 
class="Repetti" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img7.jpg" class="Storia" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/Repetti.jpg" 
class="Territorio" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img1.jpg" class="Uffizi" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img1.jpg" 
class="Associazione" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img2.jpg" class="Curiosita" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img3.jpg" class="Persone" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img4.jpg" 
class="Oltreconfine" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img5.jpg" 
class="ParcoFluviale" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/parcofluviale.jpg" 
class="Repetti" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img7.jpg" class="Storia" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/Repetti.jpg" 
class="Territorio" width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img1.jpg" class="Uffizi" 
width="160" height="120" /></div>
<div class="Miniature"><img src="img-index/img3.jpg" class="Persone" 
width="160" height="120" /></div>
 
</div>
 
 
</div>
 
 
</body>
</html>
 
Saluti
Leonardo
 
 

 immagini il link appare interrotto).
 
Ma hai provato il mio approccio? Inoltre non hai risposto alla domanda
precedente, ovvero: se puoi avere una sola classe "aperta" alla volta,
non è meglio se ti ricordi in qualche modo (oppure usi una classe/id di
appoggio) qual'è l'elemento corrente che è aperto, e chiudi solo quello?
 


Non so se hai notato, si tratta di una specie di menù per l'accesso a 
gallerie di immagini. Ad ogni immagine, facendo click sopra si accederà 
ad una galleria diversa.
All'inizio vengono mostrate tutte le miniature, poi a seconda della voce 
di menù premuta (il piccolo elenco testuale sopra  le miniature) solo un 
gruppo di miniature (di quella delle categoria premuta sul menù).
Per cui, rispondendo alla tua domanda: "puoi avere una sola classe 
"aperta" alla volta"? No, perché all'inizio o quando l'utente fa click 
su tutte, tutte le classi sono aperte. Quando poi l'utente fa click 
sulla voce di una categoria, solo una categoria rimane aperta.
Quindi alla domanda: "qual'è l'elemento corrente che è aperto"? 
all'inizio tutti, poi quando l'utente fa click su di una voce qualsiasi 
(ma non la voce tutti) è aperta solo la classe corrispondente alla voce 
sulla quale è stato fatto click. Se invece l'utente fa click su tutte, 
si torna alla configurazione di apertura pagina.
Una volta resa funzionante, la pagina, la renderò dinamica popolandola 
con i dati estratti da un database.
Il tuo approccio l'ho letto e mi ripropongo di studiarlo ed 
eventualmente applicarlo.
Per adesso la pagina l'ho resa funzionante, se vuoi te la mando perché 
so che il codice potrebbe essere scritto in maniera migliore e tu ne sai 
molto più di me su javascript.
Leonardo
 
 
 
 
 


Ti ringrazio del tempo che dedichi a cercare di farmi capire come 
scrivere del codice migliore.
L'indirizzo web dove si trova la pagina funzionante è questo:
http://www.vizzero.it/Prove/ft/index.php
 
Il jquery utilizzato è la jquery-1.7.2.min.js
Mi rendo condo che il codice che ho scritto è ridondante, ma non riesco, 
per adesso, a fare di meglio.
Per favore mi puoi un po' commentare il codice che mi hai mandato?
Grazie
Leonardo
 
 
 
 
 
 
 

dimenticavo, ho preso spunto da questo
http://www.jscraft.net/demo/plugins/filters/#
 
per il mio lavoro che è qui
http://www.vizzero.it/Prove/ft/index.php#
 
Saluti
Leonardo
 
 

 
http://www.jscraft.net/demo/plugins/filters/#
 
 
Mhm okay, allora prima che metta mano al tuo codice, perché non usi
esattamente lo stesso plugin? L'effetto finale è decisamente migliore
(non solo cambiano le dimensioni, ma anche la posizione).

>                  prev = id;
 
Alla fine di tutto, aggiorna lo stato precedente con il nuovo stato.
 
Spero di essere stato chiaro!


Credo di non capire, io l'ho scritto utilizzando solo 
jquery-1.7.2.min.js per avere jquery e istruzioni javascript/jquery e 
codice CSS scritti da me e contenuti nella pagina web.
Quindi nessun plugin.
Inoltre quello dal quale ho preso spunto utilizza una lista ordinata <ul>
<li></li>
....
<li></li>
<ul>
Per far vedere le immagini.
Io invece utilizzo un contenitore per le classi che è 
#ContenitoreMiniature al cui interno si trovano
.Miniature{
float: left;
padding-bottom: 3px;
padding-left: 3px;
}
che contengonno le immagini vere e prorpie.
Il comando: {$(".curiosita,.............uffizi").css("display","none")})
serve a far scomparire del tutto la classe delle immagini (territorio, 
curiosita ecc.).
Non va bene utilizzare hide perché il padding continua ad essere 
calcolato anche quando le dimensioni delle immagini sono a zero, e 
quindi le immagini visibili non vanno alla stessa distanza fra loro.
Leonardo
 

 quindi le immagini visibili non vanno alla stessa distanza fra loro.
 
Capisco.


 
Ho fatto questa modifica per scrivere una volta sola .animate che porta 
a zero e display none
quello che arriva con No viene trasformato in .busy1 nella stringa
Sezioni. In questo modo non viene dimensionato a zero e fatto il
display none. inoltre BUSY2 serve aa ovviare al fatto che l'ultimo non 
deve avere la virgola.
 
 
function Nascondi(No)
{var Sezioni = 
".associazioneprolastra,.curiosita,.lastrigiani,.oltreconfine,.parcofluviale,.repetti,.storia,.territorio,.uffizi,.BUSY2"; 
 
 
Sezioni = Sezioni.replace(No,".busy1,");
 
	$(Sezioni).animate({width: "0px", height: "0px"},"slow",
	function(){$(Sezioni).css("display","none")});	
}
 
Questa è una delle finzioni, le altre sono tutte simili. In questo caso 
.curiosità viene mantenuto
M adi sicuro è possibile fare di meglio.
 
$("#Curiosita").click(function () {
Nascondi(".curiosita,")
	$(".curiosita").css("display","block")	
	$(".curiosita").animate({width: "160px", height: "120px"},"slow")	
	$('.TitoloGruppoFoto').html('Curiosità');
	});
 
Saluti
Leonardo
 

     $(Sezioni).animate({width: "0px", height: "0px"},"slow",
 
In questo modo fai la query ogni volta, invece di filtrare gli elementi
che già hai (vedasi il mio codice precedente).

 che già hai (vedasi il mio codice precedente).
 
Ti ringrazio, e di sicuro sono io che non capisco.
Fra i link delle sezioni (curiosita, territorio ecc.) non sappiamo quale 
viene premuto finché non viene premuto.
Se il click è, per es., su Curiosità viene intercettato da
 
$("#Curiosita").click(function () {
Nascondi(".curiosita,")/****************/
EvidenziaImmagini(".curiosita")/***********/		
	$('.TitoloGruppoFoto').html('Curiosità');
	});
 
Da questa funzione vengono invocate altre 2 funzioni
 
function Nascondi(No)// No è la sezione da non nascondere
{var Sezioni = 
".associazioneprolastra,.curiosita,.lastrigiani,.oltreconfine,.parcofluviale,.repetti,.storia,.territorio,.uffizi,.BUSY2"; 
 
 
// viene tolta la funzione da non nascondere
Sezioni = Sezioni.replace(No,".busy1,");
 
// esegue il codice che nasconde
	$(Sezioni).animate({width: "0px", height: "0px"},"slow",
	function(){$(Sezioni).css("display","none")});	
}
 
secondo al mia logia
 
var Sezioni = 
".associazioneprolastra,.curiosita,.lastrigiani,.oltreconfine,.parcofluviale,.repetti,.storia,.territorio,.uffizi,.BUSY2";
 
deve trovarsi li perché ogni volta non sappiamo qual'è il click/sezione 
premuto e non abbiamo/dobbiamo tenere traccia di quale era la sezione 
attiva.
 
function EvidenziaImmagini(Si)// Si sezione da far vedere
{
	$(Si).css("display","block")		
	$(Si).animate({width: Larga, height: Alta},"slow");
}
 
Non riesco a capire quando scrivi "In questo modo fai la query ogni 
volta". Ogni volta il nome della sezione su cui si è fatto click è 
diverso, come posso fare ad eseguire una sola query?
Probabilmente dai per scontato qualcosa che io ignoro.
Ho pubblicato la pagina funzionante e modificata all'indirizzo
http://www.vizzero.it/Prove/ft/index.php#
 
Mi puoi spiegare in modo un po' più semplice (se esiste la possibilità)?
O qualche link per capire?
Grazie
Leonardo
 

 che già hai (vedasi il mio codice precedente).
 
O forse ho capito.
Dando ai nomi delle sezioni (al menù) la stessa classe, con this leggo 
quale è stata premuta ed in 1 unica funzione faccio
animate({width: "0px", height: "0px"},"slow",
$(Sezioni).css("display","none")}
per tutte le voci/sezioni diverse da quella premuta e
css("display","block")
animate({width: Larga, height: Alta},"slow")
per quella premuta.
Leonardo
 

 O qualche link per capire?
 
Dubito ci siano link così specifici, potrei darti link più in generale
sull'uso di JS, animazioni e jquery.


Più o meno esatto, si. Ma pensavo di averlo spiegato chiaramente nel mio
post dove analizzavo riga per riga il codice che ti avevo scritto. Se
c'è qualcosa che non ti è chiaro riprendi quel post, e quota le parti
che non ti tornano, dicendomi i tuoi dubbi, e io vedrò di chiarirteli!
 


 
Ti ringrazio per avermi fatto vedere come il lavoro andava svolto in 
modo nettamente migliore.
Penso di aver capito il funzionamento. Ho aggiunto un array associativo 
per variare il titolo in funzione del gruppo corrente.
Sul mio PC, vedendo la pagina con IE, risulta molto più lento il primo 
caricamento delle immagini rispetto a FF, Chrome e Safari. Poi però il 
funzionamento è praticamente identico fra i 4 browser.
Risulta anche a te?
Ti ringrazio.
Saluti
Leonardo
 
 
 
 

 Ti ringrazio.
 
Prego.


 
C'era anche prima.
Saluti
Leonardo
 

 C'era anche prima.
 
Allora è probabile che dipenda come ti ho detto dalla struttura HTML e
dai CSS impegnativi, se snellisci le due cose dovresti ottenere dei
benefici. C'è anche da dire che magari certe vecchie versioni di IE sono
semplicemente molto, molto lente, e quindi puoi fare comunque poco.

 che preticamente è come in PHP, ha un nome tecnico diverso?
 
Ti rimando alla spiegazione di ZER0 per cosa sono in realta`, ma ti metto 
in guardia sulla somiglianza con PHP.
 
Se fai un foreach() in PHP si comporta come un array: te li restituisce 
nell'ordine in cui li hai inseriti.
 
Se fai un for...in in JS, l'ordine e` "casuale" (non sai in che ordine te 
li torna, e cambia l'ordine di tutto se inserisci o togli elementi).
 
Ti avviso perche` ci sono rimasto scottato anche io. :D
 
Bye.

 Ti avviso perche` ci sono rimasto scottato anche io. :D
 
Premetto che sono d'accordo con te, e che non si dovrebbe contare
sull'ordine restituito dal for…in, perché a livello di specifiche è
chiaramente detto che l'ordine può essere implementato come cavolo pare
al vendor, solo con una vecchia versione di Opera mi è capitato che
l'ordine NON fosse quello cronologico di inserimento. Tutti gli altri
browser lo hanno più o meno sempre rispettato. Alla fine anche Opera si
è adeguata.
 
Ma sono d'accordo con te, che NON si dovrebbe fare affidamento
sull'ordine, e che se questo è importante allora andrebbe costruito un
oggetto apposito che ne tenga di conto.