Creëer een eenvoudig, intelligent accordeoneffect met prototype en scriptaculous

We hebben allemaal het effect van het "accordeon" -type gezien dat op veel Web 2.0-sites wordt gebruikt; Veel accordeonscripts zijn echter zwaar, maken slecht gebruik van de bibliotheken waarop ze zijn gebaseerd en behandelen niet dingen zoals ervoor zorgen dat de accordeon een consistente hoogte behoudt. In deze zelfstudie gebruiken we de Prototype- en Scriptaculous-bibliotheken om een ​​lichtgewicht, intelligente accordeon te maken.


Demo en broncode



Stap 1 - Het doel

Ons doel is om een ​​lichtgewicht accordeonscript te maken op basis van de Prototype en Scriptaculous JavaScript-bibliotheken.
De accordeon zou:

  • Laat een onbeperkt aantal accordeonruiten toe
  • Wees volledig gestyled door CSS
  • Wees onopvallend - gebruikers zonder javascript ingeschakeld zouden al uw accordeoninhoud moeten zien
  • Licht van gewicht zijn - met relatief weinig regels code; gebruik gebeurtenisafvaardiging om het geheugengebruik te beperken.
  • Ondersteun elke vorm van inhoud binnen de accordeon
  • Zorg ervoor dat wanneer de inhoud van elk accordeonpaneel verandert, de hoogte van de accordeon constant blijft om te voorkomen
    het vervelende "page bouncing" -effect

Dit is een relatief geavanceerde tutorial die veronderstelt dat de lezer een redelijke kennis heeft van Javascript, CSS, HTML, Object-Oriented
programmeren en een basisbegrip van de Prototype- en Scriptaculous-bibliotheken. Volledige broncode is echter wel
beschikbaar voor u om te studeren en de code is heel eenvoudig te lezen en te leren van als u niet bekend bent met het specifieke
bibliotheken gebruikt.

Voordat we beginnen, kun je een werkende demonstratie van de accordeon in actie zien.


Stap 2 - Begin met basisopmaak

Om te beginnen, zullen we een aantal eenvoudige HTML-markeringen voor onze accordeon creëren:

Schakel 1
Inhoud 1
Wissel 2
Inhoud 2
Schakel 3
Inhoud 3
Schakel 4
Inhoud 4

Stap 3 - Voeg een stijl toe

Vervolgens moeten we wat stijl rond onze accordeon toevoegen om het eruit te laten zien als een accordeon. Om te beginnen, doen we eerst de basisstijl en voegen we er meer aan toe als alles werkt. Er zijn ook enkele extra
stijlen die moeten worden opgenomen om ervoor te zorgen dat de accordeon correct wordt weergegeven als het animeert.

div # test-accordeon margin: 10px; border: 1px solid #aaa; div.accordion position: relative; / * vereist voor bounding - werkt rond een "eigenaardigheid" in Prototype * / div.accordion-toggle position: relative; / * vereist voor effect * / z-index: 10; / * vereist voor effect * / achtergrond: #eee; / * vereist voor effect - kan van alles zijn behalve "transparant" * / cursor: pointer;  div.accordion-toggle-active background: #fff;  div.accordion-content overflow: verborgen; / * vereist voor effect * / achtergrond: #aaa; 

Zie de basisaccordeon met een eenvoudig stylesheet.

Stap 4 - Maak de JavaScript-accordeonklasse

Prototype biedt een prachtig kader voor het bouwen van klassen in Javascript en we zullen die functionaliteit gebruiken om te bouwen
onze accordeonklas. Deze klasse bevat alle eigenschappen en methoden van een accordeon: de momenteel weergegeven
deelvenster, de inhoud van de accordeon, methoden om vensters uit te vouwen en te contracteren en methoden voor gebeurtenishandlers om te definiëren wat er gebeurt
wanneer gebruikers een actie ondernemen zoals klikken. Voor nu stellen we de basisstructuur van de klas in, evenals alle
eigenschappen en methoden die we nodig hebben:

var Accordion = Class.create (initialize: function () this.accordion = null; / * Bewaart een pointer naar het accordeonelement * / this.contents = null; / * Serie van verwijzingen naar de koppen en inhoudsvensters van de accordeon * / this.options = null; / * Staat gebruiker toe om de namen van de CSS-klassen te definiëren * / this.maxHeight = 0; / * Slaat de hoogte van het hoogste inhoudspaneel op * / this.current = null; / * Slaat een aanwijzer op in het momenteel uitgevouwen inhoudspaneel * / this.toExpand = null; / * slaat een aanwijzer op in het inhoudspaneel om uit te vouwen wanneer een gebruiker klikt * / this.isAnimating = false; / * Houdt bij of animatie al dan niet is momenteel uitgevoerd * /, checkMaxHeight: function () , / * Bepaalt de hoogte van het hoogste inhoudspaneel * / InitialHide: function () , / * Verbergt de deelvensters die standaard niet worden weergegeven * / attachInitialMaxHeight: function () , / * Garandeert dat de hoogte van het eerste inhoudsvenster overeenkomt met de hoogste * / expand: functie (el) , / * Vertelt de animatiefunctie die elem ents om te animeren * / animeren: functie () , / * Voert de daadwerkelijke animatie uit van het accordeoneffect * / handleClick: functie (e)  / * Bepaal waar een gebruiker op heeft geklikt en gehandeld op basis van die klik * / );

Dit zijn de basismethoden en eigenschappen die we nodig zullen hebben bij het bouwen van onze accordeon. Elk van de volgende stappen zal
neem je mee door elke methode te bouwen tot we een werkende accordeon hebben. Als u op enig moment tijdens de zelfstudie nodig hebt
een snelle opfriscursus over waar elke methode of eigenschap voor is, u kunt deze code met veel commentaar als een referentie gebruiken.


Stap 5 - Initialiseren: begin met dingen

Prototypeklassen hebben een speciale methode genaamd initalize (), een constructor; dit betekent dat het werkt als de gebruiker
maakt een nieuw instantieobject van die klasse. Voor elke accordeon moeten we 2 dingen weten voordat we beginnen:

  1. De id van het accordeonelement.
  2. De standaard startpositie van de accordeon (als iets anders dan de eerste positie)

We moeten onze constructor dus toestaan ​​die twee parameters te accepteren. Bovendien moet onze constructeur:

  1. Haal de accordeon en zijn inhoud op en bewaar deze als verwijzingen naar die elementen
  2. Stel de door de gebruiker gedefinieerde opties in
  3. Stel het huidige uitgevouwen element in
  4. Bepaal de maximale hoogte die we zullen gebruiken als de hoogte voor al onze inhoudsvensters en pas deze toe
  5. Verberg de inhoudsvensters die standaard niet worden getoond
  6. Voeg een gebeurtenislistener toe aan de accordeon om gebruikersklikken te bekijken.

Dit is de code voor onze initialize () -methode:

initialize: function (id, defaultExpandedCount) if (! $ (id)) throw ("Poging om de accordeon te initaliseren met id:" + id + "die niet is gevonden."); 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 ('klik', clickHandler); 

Zoals u ziet, hebben we al onze eigenschappen ingesteld op redelijke standaardwaarden en 3 methoden genoemd om dingen te helpen instellen
up. Ten slotte hebben we de gebeurtenishandler aan de accordeon bevestigd. Laten we deze drie methoden en de gebeurtenishandler maken.


Stap 6 - Het langste element controleren

Een van de vereisten voor onze accordeon is dat deze zo moet worden geschaald dat zelfs wanneer het grootste deel van de inhoud wordt uitgevouwen,
de totale accordeonhoogte blijft constant. Om dit doel te bereiken, zullen we door de inhoudsvensters heen gaan
bepalen welke de langste is en de eigenschap maxHeight dienovereenkomstig instellen:

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

Stap 7 - De rest verbergen

Onze accordeon moet alleen het inhoudspaneel weergeven dat is opgegeven als het huidige deelvenster; alle anderen moeten worden verborgen
standaard. Bovendien moeten we het height-kenmerk van dit inhoudspaneel instellen op 0; hierdoor wordt voorkomen dat het inhoudspaneel wordt weergegeven
verschijnt kort volledig geëxpandeerd voordat het goed animeert.

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

Stap 8 - Toon het standaard inhoudsvenster

Nu we alles behalve het standaard inhoudspaneel hebben verborgen, moeten we ervoor zorgen dat het standaarddeelvenster correct wordt weergegeven;
in de kop moet de "actieve" stijl worden toegepast en de hoogte moet overeenkomen met de eigenschap 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"); 

Stap 9 - Maak de gebeurtenishandler

Als u afkomstig bent van een traditionele achtergrond voor het afhandelen van gebeurtenissen, koppelen we de gebeurtenishandler aan elk gebied dat we klikbaar willen houden,
het lijkt misschien verwarrend dat we de handler slechts aan één element koppelen. Wij gebruiken evenement
delegatie
. Voor degenen onder u die onbekend zijn met het onderwerp, heb ik een korte beschrijving gegeven
overzicht van gebeurtenisafvaardiging die
zal je voorstellen aan het concept en waarom het zo belangrijk is. Dat gezegd hebbende, hebben we een intelligente gebeurtenishandler nodig:

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

Deze functie bestaat uit twee delen. Eerst bepalen we waarop is geklikt. Vervolgens controleren we of het een a was
kop waarop is geklikt en dat er momenteel geen animatie actief is. Als dit het geval is, noemen we de methode exp ()
om het proces van de accordeon te starten. De variabele die we doorgeven aan de methode expand () is de kop waarop de gebruiker heeft geklikt.


Stap 10 - Start het proces

Nu kunnen we het proces van het accordeoneffect beginnen. We weten dat de methode expand () een parameter moet gebruiken voor de
element waarop is geklikt. Met behulp van die parameter bepaalt de uitvouwmethode welk inhoudsvenster moet worden uitgebreid, en zo ja
is nog niet uitgebreid, roept de methode anim () aan om 'zijn magie te doen!'

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

Stap 11 - Het "vuile werk doen"

Op dit punt zijn alle stukken op hun plaats; we weten welk deelvenster momenteel wordt weergegeven, we weten welke kop
de gebruiker heeft geklikt en we weten welk deelvenster van de gebruiker moet worden getoond. Nu moeten we de accordeon maken
animatie. Hiervoor maken we een methode animate () die het Scriptaculous Effect gebruikt. Parallelle klasse om te renderen
de twee animaties samen; en de Effect.Scale-klasse om de grootte van elk inhoudspaneel te wijzigen. De animatie-methode zal
voer deze stappen uit:

  1. Maak een array die zal worden gebruikt om onze Effect.Scale-objecten op te slaan
  2. Verzamel de parameters die moeten worden doorgegeven aan de constructor Effect.Scale voor het inhoudspaneel dat wordt weergegeven en gemaakt
    het object
  3. Voeg dat object toe aan onze array
  4. Verzamel de parameters die moeten worden doorgegeven aan de constructor Effect.Scale voor het inhoudspaneel dat wordt verborgen en gemaakt
    het object
  5. Voeg dat object toe aan onze array
  6. Maak het Effect.Parallel-object dat onze Effect.Scale-objecten uitvoert, is sync.
  7. Vertel ons Accordion-object dat we animeren
  8. Voer de animaties uit
  9. Ruim alle stijlen op die achterblijven
  10. Vertel ons Accordion-object dat we klaar zijn met animeren
animeren: 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: waar; effects.push (nieuwe Effect.Scale (this.toExpand, 100, options)); options = sync: true, scaleContent: false, transition: Effect.Transitions.sinoidal, scaleX: false, scaleY: true; effects.push (nieuwe Effect.Scale (this.current, 0, options)); nieuw Effect.Parallel (effecten, duur: 0.5, fps: 35, wachtrij: position: 'end', scope: 'accordeon', before Start: 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)); 

Voor een volledige uitleg van de optieparameters geven we door aan zowel de effecten Effect.Scale en Effect.Parallel,
zie de Scriptaculous-documentatie.
De belangrijke aspecten van de methode zijn de eerdere Start- en AfterFinish-methoden voor ons Effect. Parallel. De voorStart
methode vertelt de accordeon dat deze momenteel animeert. Dit zal voorkomen dat de gebeurtenishandler probeert te starten
eventuele verdere wijzigingen zolang de animatie bezig is. Het zorgt er ook voor dat de kop waarop werd geklikt, is
gezien de "actieve" klassenaam. De afterFinish-methode verbergt het inhoudspaneel dat eerder werd weergegeven volledig
(nadat het is verdwenen als gevolg van de animatie). Het zorgt er ook voor dat de uiteindelijke hoogte van de nieuw weergegeven inhoud
paneel is correct. Nu de swap is voltooid, wordt aan onze accordeon verteld dat het huidige uitgebreide inhoudspaneel het
een die we onlangs hebben uitgebreid en dat de animatie is voltooid.


Stap 12 - Nog meer stijl toevoegen

Op dit punt hebben we een goed uitziende accordeon, die je hier in actie kunt zien. Maar met een beetje CSS kunnen we het allemaal veel spectaculairder laten lijken. Dus eerst maken we een snel Photoshop-mockup, zodat we een idee hebben hoe het er allemaal uit moet zien. Met dat in het achterhoofd hebben we drie afbeeldingen nodig:

  1. Een 'logo'-afbeelding -
  2. Een paar mooie achtergrondafbeeldingen - en

En hier is de herziene CSS-code:

body opvulling: 130px 50px 50px 50px; achtergrond: # 252422 url (... /img/logo.gif) geen herhaling; achtergrond-positie: 60px 40px; font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Sans-serif; font-size: 11px; regelhoogte: 18px;  div # test-accordeon border: 1px solid # 343230; achtergrondkleur: # 21201f; opvulling: 10px;  div.accordion positie: relatief; / * vereist voor bounding * / http: //net.tutsplus.com/wp-admin/users.php width: 800px;  div.accordion-toggle position: relative; / * vereist voor effect * / z-index: 10; / * vereist voor effect * / achtergrond: # 3f3c38 url (... /img/off.jpg) repeat-x; achtergrond-positie: onderaan; kleur: #fff; cursor: pointer; margin-bottom: 1px; opvulling: 9px 14px 6px 14px; border-top: 1px solid # 5d5852;  div.accordion-toggle: hover, div.accordion-toggle-active background-image: url (... /img/on.jpg); achtergrondkleur: # 6d493a; border-top: 1px solid # a06b55;  div.accordion-content overflow: verborgen; / * vereist voor effect * / achtergrond: # 302e2c; kleur: # c4bab1; border-bottom: 1px solid # 000;  div.accordion-content p margin: 9px 24px 6px 24px; 

Zoals je hier kunt zien, hebben we:

  1. Sommige achtergrondstijlen op de pagina en de accordeonklasse toegevoegd
  2. Gezien de accordeon-toggle div een regelmatige achtergrondkleur
  3. Stel de accordeonknop in: zweef en de actieve statussen om dezelfde roodachtige achtergrond te gebruiken

Stap 13 - Zie het in actie

Je kunt de werkende demonstratie hier zien. U kunt ook uw eigen CSS en afbeeldingen toevoegen
om het uiterlijk aan te passen aan uw site.

Downloaden: accordion.js & accordion.css