Lag en enkel, Intelligent Accordion Effect ved hjelp av Prototype og Scriptaculous

Vi har alle sett "trekkraft" -type-effekten som brukes på mange Web 2.0-nettsteder; Imidlertid er mange trekkspillskript tungt, gjør dårlig bruk av bibliotekene de er basert på, og håndterer ikke ting som å sikre at trekkspillet opprettholder en konsistent høyde. I denne opplæringen bruker vi Prototype og Scriptaculous-bibliotekene for å lage en lett, intelligent trekkspill.


Demo og Kildekode



Trinn 1 - Målet

Vårt mål er å lage et lett trekksprekkskript basert på Prototype og Scriptaculous javascript-biblioteker.
Trekkspillet skal:

  • Tillat et ubegrenset antall trekkspill
  • Vær helt stylet av CSS
  • Vær ikke-påtrengende-brukere uten at javascript er slått på, bør se alle dine trekkspill innhold
  • Vær lettvekt-Med relativt få linjer med kode; Bruk hendelsesdelegasjonen for å begrense minnekonsumet.
  • Støt noen form for innhold i trekkspillet
  • Forsikre deg om at når innholdet i hver trekkspane forandrer seg, forblir harmoniets høyde konstant for å unngå
    den irriterende "side bouncing" effekten

Dette er en relativt avansert opplæring som forutsetter at leseren har en rimelig kunnskap om Javascript, CSS, HTML, Object-Oriented
programmering og en grunnleggende forståelse av Prototype og Scriptaculous-biblioteker. Men fullstendig kildekoden er
tilgjengelig for deg å studere og koden er veldig enkel å lese og lære av hvis du ikke er kjent med det spesifikke
biblioteker brukt.

Før vi begynner, kan du se en fungerende demonstrasjon av trekkspillet i handling.


Trinn 2 - Begynn med Basic Markup

For å begynne, vil vi lage noen enkle HTML-oppslag for vårt trekkspill:

Bytt 1
Innhold 1
Bytt 2
Innhold 2
Bytt 3
Innhold 3
Bytt 4
Innhold 4

Trinn 3 - Legg til noen stil

Deretter må vi legge til litt stil rundt vår trekkspill for å få det til å se ut som et trekkspill. Til å begynne med vil vi gjøre et første pass på grunnleggende styling og deretter legge til flere når det hele fungerer. Det er også noen ekstra
stiler som må inkluderes for å sikre at trekkspillet vises riktig som det er animerende.

div # test-trekkspill margin: 10px; grense: 1px solid #aaa; div.accordion posisjon: relative; / * kreves for å begrense - fungerer rundt en "særegenhet" i Prototype * / div.accordion-toggle posisjon: relative; / * kreves for effekt * / z-indeks: 10; / * kreves for effekt * / bakgrunn: #eee; / * nødvendig for effekt - kan være alt unntatt "gjennomsiktig" * / markør: pointer;  div.accordion-toggle-active bakgrunn: #fff;  div.accordion-innhold overflow: hidden; / * kreves for effekt * / bakgrunn: #aaa; 

Se det grunnleggende trekkspillet med et enkelt stilark.

Trinn 4 - Opprett Javascript Accordion Class

Prototype gir et flott rammeverk for å bygge klasser i Javascript, og vi vil bruke den funksjonaliteten til å bygge
vår trekkspillklass. Denne klassen vil inneholde alle egenskapene og metodene til et trekkspill: den nåværende vises
rutenett, innholdet i trekkspillet, metoder for å utvide og kontraktsrutene, og hendelseshåndteringsmetoder for å definere hva som skjer
når brukerne tar en handling som å klikke. For nå vil vi sette opp grunnstrukturen til klassen, så vel som alle
egenskaper og metoder vi trenger:

var Accordion = Class.create (initialiser: funksjon () this.accordion = null; / * Lagrer en peker til harmonisjonselementet * / this.contents = null; / * Array av pekere til overskriftene og innholdsruten av harmoniseringen * / this.options = null; / * Lar brukeren definere navnene på css klassene * / this.maxHeight = 0; / * Lagrer høyden til det høyeste innholdspanelet * / this.current = null; / * Lagrer en peker til den utvidede innholdsruten * / this.toExpand = null; / * Lagrer en peker til innholdsruten for å utvides når en bruker klikker * / this.isAnimating = false; / * Holder styr på om animasjon er eller ikke for øyeblikket kjører * /, checkMaxHeight: funksjon () , / * Bestemmer høyden på det høyeste innholdspanelet * / initialHide: funksjon () , / * Skjuler rutene som ikke vises som standard * / attachInitialMaxHeight: funksjon () , / * Sikrer at høyden på det første innholdsruten stemmer overens med den høyeste * / expand: funksjonen (el) , / * Forteller animasjonsfunksjonen som elem ents å animere * / animere: funksjon () , / * Utfører selve animasjonen av trekkraften effekt * / handleClick: funksjon (e)  / * Bestem hvor en bruker har klikket og handle basert på det klikket * / );

Dette er de grunnleggende metodene og egenskapene vi trenger når vi bygger trekkspillet vårt. Hvert av de neste trinnene vil
Ta deg gjennom å bygge hver metode til vi har et fungerende trekkspill. Hvis som helst under opplæringen du trenger
en rask oppdatering på hva hver metode eller egenskap er for, kan du bruke denne tungt kommenterte koden som referanse.


Trinn 5 - Initialiser: Få ting startet

Prototypeklasser har en spesiell metode kalt initalize () som er en konstruktør; Dette betyr at det virker når brukeren
lager et nytt forekomstobjekt av den klassen. For et trekkspill, må vi vite 2 ting før vi begynner:

  1. Trekkspillets id.
  2. Standardspillet til trekkspillet (hvis noe annet enn den første posisjonen)

Så, vi må tillate at konstruktøren godtar disse to parametrene. I tillegg må vår konstruktør:

  1. Hent og lagre trekkspillet og dets innhold som pekere til disse elementene
  2. Angi de brukerdefinerte alternativene
  3. Sett det gjeldende utvidede elementet
  4. Bestem maksimal høyde vi vil bruke som høyde for alle våre innholdsruter og bruk den
  5. Skjul innholdsruten som ikke vises som standard
  6. Legg til en hendelseslytter til trekkspillet for å se brukerklikk.

Her er koden for vår initialiseringsmetode ():

initierer: funksjon (id, defaultExpandedCount) hvis (! $ (id)) kaste ("Forsøkt å integrere trekkspill med id:" + id + "som ikke ble funnet."); this.accordion = $ (id); this.options = toggleClass: "accordion-toggle", toggleActive: "accordion-toggle-active", contentClass: "trekkspill-innhold" 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 (dette); this.accordion.observe ('klikk', klikkHandler); 

Som du kan se, har vi satt alle våre egenskaper til fornuftige standardverdier og kalt 3 metoder for å hjelpe deg med å få ting sett
opp. Til slutt har vi festet hendelseshandleren til trekkspillet. La oss lage de tre metodene og hendelseshandleren.


Trinn 6 - Kontrollerer det høyeste elementet

En av kravene til vår trekkraft er at den må skaleres slik at selv når den høyeste innholdsruten er utvidet,
Den totale trekkhøydehøyde forblir konstant. For å oppnå dette målet vil vi gjenta det gjennom innholdsruten
bestemme hvilken som er den høyeste og angi maksimalegenskapen tilsvarende:

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

Trinn 7 - Skjul resten

Vårt trekkspill skal bare vise innholdsruten som er angitt som den nåværende ruten; alle andre skal være skjult
som standard. I tillegg må vi sette innholdsrutenes høydeattributt til 0; Dette forhindrer innholdsruten fra
Kort vises fullstendig utvidet før riktig animering.

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

Trinn 8 - Vis standardinnholdsruten

Nå som vi har skjult alt annet enn standardinnholdsruten, må vi sørge for at standardinnholdet vises riktig.
det er på vei skal ha den "aktive" stilen som brukes på den, og det er høyde som samsvarer med egenskapen maxHeight:

attachInitialMaxHeight: funksjon () this.current.previous ('div.' + this.options.toggleClass) .addClassName (this.options.toggleActive); hvis (this.current.getHeight ()! = this.maxHeight) this.current.setStyle (høyde: this.maxHeight + "px"); 

Trinn 9 - Opprett Event Handler

Hvis du kommer fra en tradisjonell hendelseshåndteringsbakgrunn der vi knytter hendelseshandleren til hvert område, vil vi klikke,
Det kan virke forvirrende at vi bare knytter håndterer til ett element. Vi bruker begivenhet
delegasjon
. For de av dere som ikke er kjent med emnet, har jeg skrevet en kort
oversikt over hendelsesdelegasjon som
vil introdusere deg til konseptet og hvorfor det er så viktig. Når det er sagt, trenger vi en intelligent hendelsehandler:

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

Det er to deler til denne funksjonen. Først bestemmer vi hva som ble klikket. Deretter sjekker vi for å sikre at det var en
overskriften som ble klikket og at ingen animasjon kjører. Hvis dette er tilfelle, kaller vi expand () -metoden
for å starte prosessen med trekkspillet. Variabelen vi overfører til expand () -metoden er overskriften som brukeren klikket på.


Trinn 10 - Start prosessen

Nå kan vi starte prosessen med å gjøre trekkspillingseffekten. Vi vet at expand () må ha en parameter for
element som ble klikket. Ved hjelp av denne parameteren bestemmer utvidelsesmetoden hvilken innholdsrute som skal utvides, og om den
er ikke allerede utvidet, kaller metoden animate () for å "gjøre sin magi!"

utvide: funksjon (el) this.toExpand = el.next ('div.' + this.options.contentClass); hvis (this.current! = this.toExpand) this.toExpand.show (); this.animate (); ,

Trinn 11 - Gjør det "skitne arbeidet"

På dette punktet er alle stykkene på plass; Vi vet hvilken innholdsrute som nå vises, vi vet hvilken overskrift
brukeren har klikket, og vi vet hvilket innholdsrute brukeren har bedt om å bli vist. Nå må vi lage trekkspillet
animasjon. For dette vil vi opprette en animate () metode som vil bruke Scriptaculous Effect.Parallel klassen til å gjengi
de to animasjonene sammen; og klasse Effect.Scale for å endre størrelsen på hver innholdsrute. Animate metoden vil
utfør disse trinnene:

  1. Opprett en matrise som vil bli brukt til å lagre våre Effect.Scale-objekter
  2. Samle parametrene for å passere til Effect.Scale-konstruktøren for innholdsruten som skal vises og opprettes
    objektet
  3. Legg det objektet i vårt utvalg
  4. Samle parametrene for å passere til Effect.Scale-konstruktøren for innholdsruten som vil bli skjult og opprett
    objektet
  5. Legg det objektet i vårt utvalg
  6. Opprett Effect.Parallel-objektet som kjører våre Effect.Scale-objekter, er synkronisert.
  7. Fortell vårt Accordion-objekt som vi animerer
  8. Kjør animasjonene
  9. Ryd opp eventuelle stiler igjen
  10. Fortell vårt Accordion-objekt som vi er ferdig med å animere
animere: funksjon () var effects = new Array (); var options = sync: true, scaleFrom: 0, scaleContent: false, overgang: Effect.Transitions.sinoidal, scaleMode: originalHeight: this.maxHeight, originalWidth: this.accordion.getWidth (), scaleX: false, scaleY: sant; effects.push (new Effect.Scale (this.toExpand, 100, alternativer)); alternativer = sync: true, scaleContent: false, overgang: Effect.Transitions.sinoidal, scaleX: false, scaleY: true; effects.push (new Effect.Scale (this.current, 0, alternativer)); ny effekt.Parallel (effekter, varighet: 0,5, fps: 35, kø: posisjon: 'ende', omfang: 'trekkspill', 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 (dette), afterFinish: funksjon () this.current.hide (); this.toExpand.setStyle (høyde: this.maxHeight + "px"); this.current = this.toExpand; this.isAnimating = false ; .bind (dette)); 

For en fullstendig forklaring på opsjonsparametrene passerer vi til både Effect.Scale og Effect.Parallel objekter,
vennligst se dokumentasjonen til Scriptaculous.
De viktige aspektene ved metoden er metodene for start og etterfining på vår Effect.Parallel. Førstart
Metoden forteller trekkspillet at det for øyeblikket er animert. Dette vil forhindre at hendelseshåndtereren forsøker å starte
noen ytterligere endringer så lenge animasjonen pågår. Det sørger også for at overskriften som ble klikket er
gitt det "aktive" klassenavnet. AfterFinish-metoden gjemmer helt innholdsruten som tidligere hadde blitt vist
(etter at den er forsvunnet på grunn av animasjonen). Det sikrer også at slutthøyden til det nylig viste innholdet
ruten er riktig. Nå som bytteprogrammet er ferdig, forteller det vårt trekkspill at den utvidede innholdsruten er den
en vi har nylig utvidet og at animasjonen er fullført.


Trinn 12 - Legger til litt mer stil

På dette punktet har vi et anstendig utseende trekkspill, som du kan se i aksjon her. Men med en liten CSS kan vi få det til å se alt mer spektakulært ut. Så først oppretter vi en rask Photoshop mockup, så vi har en grov ide om hvordan det skal se ut. Med det i tankene, trenger vi tre bilder:

  1. Et "logo" -bilde -
  2. Et par fine bakgrunnsbilder - og

Og her er den reviderte CSS-koden:

kropp polstring: 130px 50px 50px 50px; bakgrunn: # 252422 url (... /img/logo.gif) no-repeat; bakgrunnsposisjon: 60px 40px; font-familie: "Lucida Grande", "Lucida Sans Unicode", Arial, Sans-serif; skriftstørrelse: 11px; linjehøyde: 18px;  div # test-trekkspill border: 1px solid # 343230; bakgrunnsfarge: # 21201f; polstring: 10px;  div.accordion posisjon: relative; / * kreves for å begrense * / http: //net.tutsplus.com/wp-admin/users.php bredde: 800px;  div.accordion-toggle posisjon: relative; / * kreves for effekt * / z-indeks: 10; / * kreves for effekt * / bakgrunn: # 3f3c38 url (... /img/off.jpg) repeat-x; bakgrunnsposisjon: bunn; farge: #fff; markør: pointer; margin-bunn: 1px; polstring: 9px 14px 6px 14px; border-top: 1px solid # 5d5852;  div.accordion-toggle: svever, div.accordion-toggle-active bakgrunnsbilde: url (... /img/on.jpg); bakgrunnsfarge: # 6d493a; border-top: 1px solid # a06b55;  div.accordion-innhold overflow: hidden; / * kreves for effekt * / bakgrunn: # 302e2c; farge: # c4bab1; border-bottom: 1px solid # 000;  div.accordion-innhold p margin: 9px 24px 6px 24px; 

Som du kan se her har vi:

  1. Lagt til noen bakgrunnsstiler rundt siden og trekkspillklassen
  2. Gitt accordion-toggle div en vanlig bakgrunnsfarge
  3. Still inn trekkspillet: sving og de aktive delene å bruke den samme rødlige bakgrunnen

Trinn 13 - Se det i aksjon

Du kan se arbeidsdemonstrasjonen her. Du kan også legge til eget CSS og bilder
å skreddersy utseendet til nettstedet ditt.

Last ned: accordion.js & accordion.css