Crea un effetto di fisarmonica semplice e intelligente usando Prototype e Scriptaculous

Tutti abbiamo visto l'effetto del tipo "fisarmonica" usato su molti siti Web 2.0; tuttavia, molti script di fisarmonica sono pesanti, fanno un uso scadente delle librerie su cui si basano e non gestiscono le cose, ad esempio assicurando che la fisarmonica mantenga un'altezza costante. In questo tutorial, utilizzeremo le librerie Prototype e Scriptaculous per creare una fisarmonica leggera e intelligente.


Demo e codice sorgente



Step 1 - The Goal

Il nostro obiettivo è creare uno script di fisarmonica leggero basato sulle librerie javascript Prototype e Scriptaculous.
La fisarmonica dovrebbe:

  • Consenti un numero illimitato di riquadri a fisarmonica
  • Completamente stilizzato dai CSS
  • Essere discreto: gli utenti senza javascript attivati ​​dovrebbero vedere tutti i contenuti della fisarmonica
  • Sii leggero - Con relativamente poche righe di codice; utilizzare la delega degli eventi per limitare il consumo di memoria.
  • Supporta qualsiasi tipo di contenuto all'interno della fisarmonica
  • Assicurarsi che quando il contenuto di ogni riquadro della fisarmonica cambia, l'altezza della fisarmonica rimane costante da evitare
    il fastidioso effetto "rimbalzo della pagina"

Questo è un tutorial relativamente avanzato che presuppone che il lettore abbia una conoscenza ragionevole di Javascript, CSS, HTML, Object-Oriented
programmazione e una conoscenza di base delle librerie Prototype e Scriptaculous. Tuttavia, il codice sorgente completo è
disponibile per voi per studiare e il codice è molto semplice da leggere e imparare da se non si ha familiarità con lo specifico
librerie usate.

Prima di iniziare, puoi vedere una dimostrazione di lavoro della fisarmonica in azione.


Passaggio 2: iniziare con il markup di base

Per iniziare, creeremo un semplice markup HTML per la nostra fisarmonica:

Attiva 1
Contenuto 1
Attiva / disattiva 2
Contenuto 2
Attiva / disattiva 3
Contenuto 3
Attiva / disattiva 4
Contenuto 4

Passaggio 3: aggiungi un po 'di stile

Successivamente, abbiamo bisogno di aggiungere uno stile attorno alla nostra fisarmonica per farlo sembrare una fisarmonica. Per cominciare, faremo una prima passata dello styling di base e aggiungeremo di più quando tutto funziona. Ci sono anche alcuni aggiuntivi
stili che devono essere inclusi per garantire che la fisarmonica venga visualizzata correttamente durante l'animazione.

div # test-accordion margin: 10px; border: 1px solid #aaa; div.accordion position: relative; / * richiesto per il limite - funziona attorno a una "particolarità" in Prototype * / div.accordion-toggle position: relative; / * richiesto per effetto * / z-index: 10; / * richiesto per effetto * / background: #eee; / * richiesto per l'effetto - può essere qualsiasi cosa eccetto "transparent" * / cursor: pointer;  div.accordion-toggle-active background: #fff;  div.accordion-content overflow: hidden; / * richiesto per effetto * / background: #aaa; 

Guarda la fisarmonica di base con un semplice foglio di stile.

Passaggio 4: crea la classe di fisarmonica Javascript

Prototype fornisce un meraviglioso framework per la creazione di classi in Javascript e useremo questa funzionalità per creare
la nostra lezione di fisarmonica. Questa classe conterrà tutte le proprietà e i metodi di una fisarmonica: quella attualmente visualizzata
riquadro, i contenuti della fisarmonica, i metodi per espandere e contrarre i riquadri ei metodi del gestore eventi per definire cosa succede
quando gli utenti intraprendono un'azione come fare clic. Per ora, imposteremo la struttura di base della classe e tutti i
proprietà e metodi di cui avremo bisogno:

var Accordion = Class.create (initialize: function () this.accordion = null; / * Memorizza un puntatore all'elemento fisarmonica * / this.contents = null; / * Matrice di puntatori alle intestazioni e ai riquadri dei contenuti di la fisarmonica * / this.options = null; / * Consente all'utente di definire i nomi delle classi css * / this.maxHeight = 0; / * Memorizza l'altezza del riquadro di contenuto più alto * / this.current = null; / * Memorizza un puntatore al riquadro del contenuto attualmente espanso * / this.toExpand = null; / * Memorizza un puntatore al riquadro del contenuto per espandere quando un utente fa clic * / this.isAnimating = false; / * Tiene traccia di se l'animazione è o meno correntemente * /, checkMaxHeight: function () , / * Determina l'altezza del riquadro del contenuto più alto * / initialHide: function () , / * Nasconde i riquadri che non vengono visualizzati per impostazione predefinita * / attachInitialMaxHeight: function () , / * Garantisce che l'altezza del primo riquadro del contenuto corrisponda al più alto * / espandi: function (el) , / * Indica la funzione di animazione che elem ents to animate * / animate: function () , / * Esegue l'animazione effettiva dell'effetto fisarmonica * / handleClick: function (e)  / * Determina dove un utente ha fatto clic e agisce in base a quel clic * / );

Questi sono i metodi e le proprietà di base di cui avremo bisogno quando costruiamo la nostra fisarmonica. Ognuno dei prossimi passi lo farà
portati a costruire ogni metodo fino a quando non avremo una fisarmonica funzionante. Se in qualsiasi momento durante il tutorial è necessario
un rapido aggiornamento su ciò che ciascun metodo o proprietà è per, è possibile utilizzare questo codice fortemente commentato come riferimento.


Passaggio 5: Inizializza: avvia le cose

Le classi di prototipi hanno un metodo speciale chiamato initalize () che è un costruttore; questo significa che agisce quando l'utente
crea un nuovo oggetto istanza di quella classe. Per qualsiasi fisarmonica, dobbiamo conoscere 2 cose prima di iniziare:

  1. L'id dell'elemento fisarmonica.
  2. La posizione di partenza predefinita della fisarmonica (se diversa dalla prima posizione)

Quindi, dovremo consentire al nostro costruttore di accettare questi due parametri. Inoltre, il nostro costruttore deve:

  1. Recupera e archivia la fisarmonica e il suo contenuto come puntatori a tali elementi
  2. Imposta le opzioni definite dall'utente
  3. Imposta l'elemento espanso corrente
  4. Determina l'altezza massima che useremo come altezza per tutti i nostri riquadri di contenuti e applicala
  5. Nascondere i riquadri dei contenuti che non sono visualizzati per impostazione predefinita
  6. Aggiungi un listener di eventi alla fisarmonica per monitorare i clic dell'utente.

Ecco il codice per il nostro metodo initialize ():

initialize: function (id, defaultExpandedCount) if (! $ (id)) throw ("Tentativo di initalizzare la fisarmonica con id:" + id + "che non è stato trovato."); this.accordion = $ (id); this.options = toggleClass: "accordion-toggle", toggleActive: "accordion-toggle-active", contentClass: "accordion-content" this.contents = this.accordion.select ('div.' + this.options. ContentClass); this.isAnimating = false; this.maxHeight = 0; this.current = defaultExpandedCount? this.contents [defaultExpandedCount-1]: this.contents [0]; this.toExpand = null; this.checkMaxHeight (); this.initialHide (); this.attachInitialMaxHeight (); var clickHandler = this.clickHandler.bindAsEventListener (this); this.accordion.observe ('click', clickHandler); 

Come puoi vedere, abbiamo impostato tutte le nostre proprietà su valori predefiniti ragionevoli e abbiamo chiamato 3 metodi per ottenere le cose a posto
su. Infine, abbiamo allegato il gestore di eventi alla fisarmonica. Creiamo questi tre metodi e il gestore di eventi.


Passaggio 6: controllo dell'elemento più alto

Uno dei requisiti per la nostra fisarmonica è che deve scalare in modo tale che anche quando il riquadro del contenuto più alto viene espanso,
l'altezza complessiva della fisarmonica rimarrà costante. Per raggiungere questo obiettivo, continueremo a scorrere i riquadri dei contenuti
determinare quale è il più alto e impostare di conseguenza la proprietà maxHeight:

checkMaxHeight: function () for (var i = 0; i this.maxHeight) this.maxHeight = this.contents [i] .getHeight (); 

Passaggio 7 - Nascondere il resto

La nostra fisarmonica dovrebbe visualizzare solo il riquadro del contenuto specificato come riquadro corrente; tutti gli altri dovrebbero essere nascosti
per impostazione predefinita. Inoltre, abbiamo bisogno di impostare l'attributo height di questo riquadro del contenuto su 0; questo impedisce al pannello del contenuto di
appare brevemente completamente espanso prima di animare correttamente.

initialHide: function () for (var i = 0; i 

Passaggio 8: mostra il riquadro del contenuto predefinito

Ora che abbiamo nascosto tutto tranne il riquadro del contenuto predefinito, dobbiamo assicurarci che il riquadro del contenuto predefinito sia visualizzato correttamente;
la sua intestazione dovrebbe avere lo stile "attivo" applicato e la sua altezza dovrebbe corrispondere alla proprietà maxHeight:

attachInitialMaxHeight: function () this.current.previous ('div.' + this.options.toggleClass) .addClassName (this.options.toggleActive); if (this.current.getHeight ()! = this.maxHeight) this.current.setStyle (height: this.maxHeight + "px"); 

Passaggio 9: creare il gestore eventi

Se provieni da uno sfondo di gestione degli eventi tradizionale in cui colleghiamo il gestore di eventi a ciascuna area che vogliamo selezionabile,
può sembrare confuso il fatto che stiamo solo assegnando il gestore a un elemento. Stiamo usando evento
delegazione
. Per quelli di voi che non conoscono l'argomento, ho scritto un breve
panoramica della delega degli eventi che
ti introdurrà al concetto e perché è così importante. Detto questo, abbiamo bisogno di un gestore di eventi intelligente:

clickHandler: function (e) var el = e.element (); if (el.hasClassName (this.options.toggleClass) &&! this.isAnimating) this.expand (el); 

Ci sono due parti per questa funzione. In primo luogo, determiniamo ciò che è stato cliccato. Quindi, controlliamo per assicurarsi che fosse un
intestazione su cui è stato fatto clic e che al momento non è in esecuzione alcuna animazione. In questo caso, chiamiamo il metodo expand ()
per iniziare il processo della fisarmonica. La variabile passata al metodo expand () è l'intestazione su cui l'utente ha fatto clic.


Passaggio 10: avviare il processo

Ora possiamo iniziare il processo di esecuzione dell'effetto fisarmonica. Sappiamo che il metodo expand () deve prendere un parametro per il
elemento su cui è stato fatto clic. Utilizzando tale parametro, il metodo di espansione determina quale riquadro del contenuto deve espandersi e se lo è
non è già espanso, chiama il metodo animate () per "fare la sua magia!"

expand: function (el) this.toExpand = el.next ('div.' + this.options.contentClass); if (this.current! = this.toExpand) this.toExpand.show (); this.animate (); ,

Step 11 - Fare il "lavoro sporco"

A questo punto, tutti i pezzi sono a posto; sappiamo quale riquadro del contenuto è attualmente visualizzato, sappiamo quale titolo
l'utente ha fatto clic e sappiamo quale riquadro del contenuto l'utente ha richiesto di mostrare. Ora, dobbiamo creare la fisarmonica
animazione. Per questo, creeremo un metodo animate () che utilizzerà la classe Scriptaculous Effect.Parallel per il rendering
le due animazioni insieme; e la classe Effect.Scale per modificare le dimensioni di ogni riquadro del contenuto. Il metodo animato lo farà
eseguire questi passaggi:

  1. Crea una matrice che verrà utilizzata per memorizzare i nostri oggetti Effect.Scale
  2. Raccogli i parametri per passare al costruttore Effect.Scale per il riquadro del contenuto che verrà mostrato e creato
    l'oggetto
  3. Aggiungi quell'oggetto al nostro array
  4. Raccogliere i parametri per passare al costruttore Effect.Scale per il riquadro del contenuto che verrà nascosto e creato
    l'oggetto
  5. Aggiungi quell'oggetto al nostro array
  6. Crea l'oggetto Effect.Parallel che eseguirà i nostri oggetti Effect.Scale è sincronizzato.
  7. Dì al nostro oggetto Fisarmonica che stiamo animando
  8. Esegui le animazioni
  9. Pulisci tutti gli stili rimasti indietro
  10. Dì al nostro oggetto Fisarmonica che abbiamo finito di animare
animate: function () var effects = new Array (); var options = sync: true, scaleFrom: 0, scaleContent: false, transition: Effect.Transitions.sinoidal, scaleMode: originalHeight: this.maxHeight, originalWidth: this.accordion.getWidth (), scaleX: false, scaleY: vero ; effects.push (new Effect.Scale (this.toExpand, 100, options)); options = sync: true, scaleContent: false, transition: Effect.Transitions.sinoidal, scaleX: false, scaleY: true; effects.push (new Effect.Scale (this.current, 0, options)); nuovo Effect.Parallel (effetti, duration: 0.5, fps: 35, queue: position: 'end', scope: 'accordion', beforeStart: function () this.isAnimating = true; this.current.previous ( 'div.' + this.options.toggleClass) .removeClassName (this.options.toggleActive); this.toExpand.previous ('div.' + this.options.toggleClass) .addClassName (this.options.toggleActive);. bind (this), afterFinish: function () this.current.hide (); this.toExpand.setStyle (height: this.maxHeight + "px"); this.current = this.toExpand; this.isAnimating = false ; .bind (this)); 

Per una spiegazione completa dei parametri delle opzioni stiamo passando ad entrambi gli oggetti Effect.Scale ed Effect.Parallel,
per favore vedi la documentazione Scriptaculous.
Gli aspetti importanti del metodo sono i metodi beforeStart e afterFinish sul nostro Effect.Parallel. The beforeStart
metodo dice alla fisarmonica che sta attualmente animando. Ciò impedirà al gestore di eventi di tentare di avviarsi
eventuali ulteriori modifiche fintanto che l'animazione è in corso. Si assicura anche che l'intestazione su cui è stato fatto clic sia
dato il nome della classe "attivo". Il metodo afterFinish nasconde completamente il riquadro del contenuto che era stato precedentemente visualizzato
(dopo che è scomparso a causa dell'animazione). Garantisce inoltre l'altezza finale del contenuto visualizzato di recente
il riquadro è corretto. Ora che lo scambio è completo, dice alla nostra fisarmonica che il riquadro del contenuto attualmente espanso è il
uno che abbiamo appena ampliato e che l'animazione è completa.


Passaggio 12: aggiunta di un altro stile

A questo punto abbiamo una fisarmonica dall'aspetto decente, che puoi vedere in azione qui. Ma con un po 'di CSS possiamo far sembrare tutto molto più spettacolare. Quindi prima creiamo un rapido mockup di Photoshop, quindi abbiamo una vaga idea di come dovrebbe apparire. Con questo in mente, avremo bisogno di tre immagini:

  1. Un'immagine 'logo' -
  2. Un paio di belle immagini di sfondo - e

Ed ecco il codice CSS revisionato:

body padding: 130px 50px 50px 50px; background: # 252422 url (... /img/logo.gif) no-repeat; posizione di sfondo: 60px 40px; famiglia di font: "Lucida Grande", "Lucida Sans Unicode", Arial, Sans-Serif; font-size: 11px; altezza della linea: 18px;  div # test-accordion border: 1px solid # 343230; background-color: # 21201f; imbottitura: 10px;  div.accordion position: relative; / * richiesto per il limite * / http: //net.tutsplus.com/wp-admin/users.php width: 800px;  div.accordion-toggle position: relative; / * richiesto per effetto * / z-index: 10; / * richiesto per effect * / background: # 3f3c38 url (... /img/off.jpg) repeat-x; posizione di fondo: fondo; colore: #fff; cursore: puntatore; margin-bottom: 1px; imbottitura: 9px 14px 6px 14px; border-top: 1px solid # 5d5852;  div.accordion-toggle: hover, div.accordion-toggle-active background-image: url (... /img/on.jpg); background-color: # 6d493a; border-top: 1px solid # a06b55;  div.accordion-content overflow: hidden; / * richiesto per effetto * / background: # 302e2c; colore: # c4bab1; border-bottom: 1px solid # 000;  div.accordion-content p margin: 9px 24px 6px 24px; 

Come puoi vedere qui abbiamo:

  1. Aggiunti alcuni stili di sfondo attorno alla pagina e alla classe di fisarmonica
  2. Dato il div-switch con fisarmonica, un colore di sfondo regolare
  3. Imposta l'interruttore a fisarmonica: passa il mouse e gli stati attivi per utilizzare lo stesso sfondo rossastro

Step 13 - Guardalo in azione

Puoi vedere la dimostrazione di lavoro qui. Puoi anche aggiungere il tuo CSS e le tue immagini
per adattare il look al tuo sito.

Scarica: accordion.js e accordion.css