Bygg en jQuery Image Scroller

I denne opplæringen skal vi bygge en bildeskriver, og benytte jQuerys utmerkede animasjonsfunksjoner og ha generelt mye moro med kode. Bildrullere er selvfølgelig ikke noe nytt; Versjoner av dem kommer ut hele tiden. Mange av dem er imidlertid brukerinitierte; noe som betyr at for at det viste innholdet skal endres, må den besøkende klikke på en knapp eller utføre annen handling. Denne scroller vil være annerledes ved at den blir helt autonom og begynner å rulle når siden laster.


Den ferdige widgeten vil være fullstendig kryssbrowser og utføre som forventet i de nyeste versjonene av alle de vanligste nettleserne. Vi vil også bygge inn noe samspill ved å legge til kontroller som gjør det mulig for besøkende å endre animasjonsretningen. Vi jobber med bare jQuery og litt HTML og CSS i denne opplæringen og skal kunne kjøre eksemplene uten en fullstendig webserveroppsett.


Starter

La oss lage den underliggende HTML-siden først og fremst; I en ny side i tekstredigereren legger du til følgende kode:

      ImageScroller Image Carousel   
eple Firefox jQuery Twitter jQuery brukergrensesnitt

Lagre dette som imageScroller.html inne i en ny mappe. Vi lenker til et tilpasset stilark i hodet på siden, som vi vil kode om en liten stund, og vi inkluderer en kobling til den vertsbaserte versjonen av den nyeste versjonen av jQuery nederst på siden. Lasting av skript i enden av kroppen er en anerkjent teknikk for å forbedre ytelsen til siden din og bør derfor praktiseres der det er mulig.

Vår widget består av en rekke nestede containere og en rekke bilder innpakket i koblinger. Bildene som er plassert i beholderne, er hardkodede inn på siden av tilgjengelighetshensyn. Vi vil ikke hente bildene dynamisk; Alle bilder som er plassert i widgeten, blir automatisk rullet (forutsatt at de er pakket inn i en kobling med riktig klassenavn).

Den ytterste beholderen vil bli brukt primært for posisjons- og displayformål, mens den neste beholderen brukes til å dekorere widgeten med et bakgrunnsbilde. Den ytre beholderen er også nødvendig for å legge til kontrollene slik at de vises over innholdet riktig i IE.

Den innerste beholderen er elementet som vil bli brukt til å se bildene gjennom. Dette elementet er gitt klassen js-disabled, som bare vil bli brukt til besøkende som har JavaScript deaktivert. Vi bruker denne klassen til å krympe hver av bildene med CSS slik at de alle kan ses.

Bildene er alle ensartede, og beholderne vil bli dimensjonert for å imøtekomme dem ganske pent. Bildestørrelsen brukes også i skriptet som vi legger til; Jeg vil markere spesielt hvor disse referansene oppstår, men du bør være oppmerksom på at hvis du vil bruke bilder av forskjellig størrelse, må skriptet og størrelsen på beholderne justeres tilsvarende.


Styling Widget

Etter koblingen til jQuery har vi et tilpasset skriptelement med jQuery document.ready snarvei, og venter på at vi legger til koden som vil bringe widgeten til livs. Før vi gjør det, la oss bare legge til CSS raskt. I en annen ny fil i tekstredigeringsprogrammet legger du til følgende valg- og stilregler:

 / * js-deaktivert klasse - angi bildestørrelser slik at de alle passer i seeren * / .js-disabled img width: 100px; høyde: 100 piksler; display: block; float: venstre; margin: 30px 0 0;  #outerContainer width: 542px; høyde: 202px; margin: auto; stilling: i forhold;  #imageScroller width: 542px; høyde: 202px; stilling: i forhold; bakgrunn: # 000000 url (images / imageScrollerBG.png) no-repeat;  #viewer width: 522px; høyde: 182px; flow: hidden; margin: auto; stilling: i forhold; top: 10px;  #imageScroller a: active, #imageScroller a: besøkt farge: # 000000;  #imageScroller a img border: 0;  #controls width: 534px; høyde: 47px; bakgrunn: url (images / controlsBG.png) no-repeat; stilling: absolutt; top: 4px; venstre: 4px; z-indeks: 10;  # kontrollerer en bredde: 37px; høyde: 35px; stilling: absolutt; top: 3px;  #controls a: active, #controls a: besøkt farge: # 0d0d0d;  #title color: #ffffff; font-family: arial; font-size: 100%; font-vekt: bold; bredde: 100%; tekst-Justering: center; margin-top: 10px;  #rtl bakgrunn: url (images / rtl.png) no-repeat; venstre: 100px;  #rtl: svever bakgrunn: url (images / rtl_over.png) no-repeat; venstre: 99px;  #ltr bakgrunn: url (images / ltr.png) no-repeat; høyre: 100px;  #ltr: hover background: url (images / ltr_over.png) no-repeat; 

Hvis JavaScript er deaktivert, og mens siden lastes inn, vil alle bildene bli synlige

Lagre dette som imageScroller.css i samme mappe som nettsiden. Først har vi klassevalgeren som retter seg mot vår js-funksjonshemmede klasse; Med disse reglene lagrer vi bare bildene slik at de er små nok til å stable opp ved siden av hverandre langs bredden på widgeten. Hvis JavaScript er deaktivert, og mens siden lastes inn, vil alle bildene bli synlige - en veldig rask og enkel nedgang, men en som ikke nødvendigvis er idiotsikker og absolutt ikke er fullført Progressiv forbedring. Verdiene som er spesifisert for bredde og høyde, må variere avhengig av antall bilder i seeren.

Etter dette har vi selektorer og regler som stiler widgeten og får den til å fungere riktig. Mesteparten av koden er her for visning, bakgrunnsbilder, farger, etc. En viktig regel, som implementeringen er avhengig av å fungere riktig, er innstillingen av overløp: skjult på den indre seerbeholderen. Dette vil gjemme bildene som ennå ikke skal vises, og bildene som allerede har gått gjennom seeren. På dette stadiet når vi kjører siden, bør vi se noe slikt:

Noen av CSS vil vi sette inn i JavaScript på et øyeblikk, og noen av elementene som vi målretter mot i CSS eksisterer ikke ennå, men dette er alt som trenger å gå inn i CSS-filen.


Ta med widgeten til livet

I den siste fasen av denne opplæringen legger vi til jQuery-smaksatt JavaScript som gjør widgeten i arbeid og skaper den oppførelsen vi ønsker. Innenfor den tomme anonyme funksjonen nederst på HTML-siden legger du til følgende kode:

 // fjern js-deaktivert klasse $ ("# viewer"). removeClass ("js-disabled"); // Opprett ny container for bilder $ ("
") .attr (" id "," container "). css (posisjon:" absolutt ") bredde ($ (" wrapper "). lengde * 170) .height (170) .appendTo viewer "); // legge bilder til container $ (" wrapper "). hver (funksjon () $ (denne) .appendTo (" div # container ");); // trene lengden på anim basert på antall bilder (1 sekund for hvert bilde) var duration = $ ("wrapper"). lengde * 1000; // butikkhastighet for senere varhastighet = (parseInt ($ ("div # container"). bredde + parseInt ($ ("div # viewer"). bredde ())) / varighet; // sett retning var retning = "rtl"; // angi startposisjon og klasse basert på retning (retning == "rtl")? css ("left", $ ("div # viewer"). bredde ()). addClass ("rtl"): $ ("div # container" , 0 - $ ("div # container"). Bredde ()). AddClass ("ltr");

Først av alt fjerner vi klassen js-deaktivert fra seerbeholderen. Deretter oppretter vi en ny container for å holde alle bildene som finnes i widgeten. Hovedårsaken til dette er at i stedet for å animere hvert bilde enkeltvis, noe som resulterer i et potensielt stort antall animasjoner som kjører samtidig, trenger vi bare å animere ett element - beholderen som vi lager nå.

Bredden på den nye beholderen er satt til antall bilder multiplisert med bredden på hvert bilde, som i dette eksemplet er 170 piksler. Dette er en av kodene som jeg sa tidligere, jeg vil spesifikt nevne, og er noe som må endres hvis vi bestemmer oss for å bruke bilder av forskjellig størrelse. Høyden på beholderen er også spesifikt satt til høyden på hvert bilde.

Det er nyttig senere i skriptet å vite visse ting om animasjonens natur, for eksempel hastigheten, varigheten den varer og reisen, så vi neste sett en rekke variabler for å lagre denne informasjonen i. varigheten vil ligge til nøyaktig ett sekund per bilde, og er igjen basert på antall bilder som finnes i widgeten.

Hastigheten er lett å trene, selvfølgelig er avstanden for reise delt med reisens varighet. Til referanse, i dette eksemplet vil den eksakte hastigheten til animasjonen være 0,274 piksler per millisekund. Den endelige variabelen, retning, er en enkel streng som indikerer at animasjonen vil fortsette fra høyre til venstre, selv om vi lett kunne endre dette til ltr hvis vi ønsket.

Endelig setter vi startposisjonen til den nye beholderen; Siden animasjonen for øyeblikket er satt til rtl, må vi plassere den nye bildebeholderen slik at den venstre kanten er satt til høyre kant av betrakteren. Hvis vi stiller animasjonen til ltr, vil elementets høyre kant imidlertid justeres med beholderens venstre kant. Vi bestemmer retningen ved hjelp av JavaScript ternær betinget. I tillegg til sin posisjon gir vi også den nye containeren et klassenavn som samsvarer med retningen, som vi kan teste på på forskjellige punkter i skriptet.

Deretter må vi definere en ny funksjon for å initiere og fortsette animasjonen. Det er flere forskjellige tider under normal utførelse av skriptet som vi må begynne å animere, slik at innpakning av denne funksjonaliteten i en funksjon som vi kan ringe når vi trenger, bidrar til å redusere mengden kode. Legg til følgende kode:

 / // animator funksjon var animator = funksjon (el, tid, dir) // hvilken retning å bla om (dir == "rtl") // legg til retning klasse el.removeClass ("ltr"). addClass ("rtl "); // animere el el.animate (left: "-" + el.width () + "px", tid, "lineær", funksjon () // tilbakestill beholderposisjon $ (dette) .css ( venstre: $ ("div # imageScroller"). bredde (), høyre: "") / / start animasjons animator ($ (dette), varighet, "rtl"); // skjul kontroll hvis synlig div # kontroller "). lengde> 0)? $ (" div # controls "). slideUp (" slow "). fjern (): null;);  ellers // legg retningsklasse el.removeClass ("rtl"). addClass ("ltr"); // animere el el.animate (left: $ ("div # viewer"). bredde () + "px", tid, "lineær", funksjon () // tilbakestill beholderposisjon $ (dette). css (left: 0 - $ ("div # container"). bredde ()) / / start animasjon animator ($ (denne), varighet, "ltr"); // skjul kontroller hvis synlig div # kontroller "). lengde> 0)? $ (" div # controls "). slideUp (" slow "). fjern (): null;); 

Animasjonsfunksjonen aksepterer tre argumenter; elementet til å animere, hvor lang tid animasjonen skal løpe for, og retningen der elementet skal animeres. Funksjonen er oppdelt i to forskjellige blokker, en for rtl animasjon og den andre for ltr.

Innenfor hver blokk av betinget oppdaterer vi klassenavnet til bildebeholderen for å reflektere den aktuelle retningen bare i tilfelle retningen har endret seg (dette er en av de besøkende initierte interaksjonene).

Vi definerer deretter animasjonen, flytter bildebeholderen pluss for ltr eller minus for rtl bredden på bildebeholderen, noe som gir det inntrykk av å glide over seeren. Dessverre kan vi ikke bruke den innebygde langsomme, normale eller raske animasjoner, fordi selv den langsomme innstillingen begrenser animasjonen til en total kjøretid på bare 600 millisekunder, noe som er altfor fort for det lille antallet bilder vi bruker i dette eksemplet.

Vi spesifiserer strengen lineær som det tredje argumentet til animasjonsmetoden som er lettelsefunksjonen som skal brukes, og setter animasjonen til å fortsette med en jevn hastighet fra start til slutt; hvis vi ikke satte dette, ville animasjonen synlig øke hastigheten og avta ved begynnelsen og slutten av animasjonen henholdsvis.

Til slutt legger vi til en anonym tilbakeringingsfunksjon som vil bli utført så snart animasjonen slutter. I denne tilbakekallingsfunksjonen returnerer vi bildebeholderen til startposisjonen, rekursivt kalder animatorfunksjonen igjen i de riktige innstillingene, avhengig av hvilken gren av betinget som kjøres, og skjul kontrollpanelet hvis det er synlig. Vi har ikke lagt til koden som vil opprette kontrollpanelet ennå, men vi må fortsatt legge til denne koden her for når vi har.

For å starte animasjonen når siden har laster, må vi nå ringe til funksjonen som vi nettopp har definert. legg til følgende funksjonsanrop:

 // start anim animator ($ ("div # container"), varighet, retning);

Alt vi gjør er å ringe funksjonen som passerer i elementet for å animere og variablene vi satt i den første delen av koden. Hvis vi kjører siden nå, bør vi oppdage at animasjonen starter så snart siden har lastet inn og fortsetter på ubestemt tid, som vist (slags) i følgende skjermdump:


Legger til noen interaksjon

Vi er nå på scenen hvor vi har kjernefunksjonaliteten til widgeten, og kan begynne å legge til den ekstra interaktiviteten som vil gjøre det engasjerende. Etter anropet til animatorfunksjonen legger du til følgende kode:

 / / pause på mouseover $ ("a.wrapper"). live ("mouseover", funksjon () // stopp anim $ ("div # container" div # kontroller "). lengde == 0)? $ ("

Som kommentaren indikerer, vil denne hendelsesbehandleren stoppe animasjonen når besøkende svever pekeren på et av bildene i widgeten.

Vi bruker metoden live jQuery (ny til 1,3!) For å feste håndterer til elementene og angi en anonym funksjon som skal utføres når hendelsen oppstår.

Innenfor denne funksjonen stopper vi først animasjonen ved hjelp av jQuery-stoppmetoden, og sender inn en ekte boolsk verdi som et argument. Dette argumentet vil avbryte animasjonskøen hvis den eksisterer; det burde ikke gjøre, da det bare skulle være en animasjon på en gang, men det er nyttig å bruke dette argumentet bare i tilfelle.

Vi kontrollerer om kontrollpanelet allerede eksisterer, og forutsatt at det ikke oppretter vi et nytt div-element, gi det et ID slik at det plukker opp våre stilregler og legger det til den ytre beholderen. Vi bruker deretter jQuery's css-metode for å sette opaciteten i en kryssbrowser-mote for å unngå å måtte målrette mot forskjellige nettlesere med vårt CSS, og skyv kontrollene på plass.

Vi lager også noen koblinger og legger dem til kontrollpanelet; Disse koblingene vil fungere som knapper som gjør det mulig for besøkende å endre retningen som bildene beveger seg. Vi legger til håndtere for disse knappene i et øyeblikk. Til slutt får vi innholdet i tittelattributtet til wrapper-lenken som utløste mouseover-hendelsen, og oppretter et nytt avsnitt med sin indre tekst satt til tittelen. Vi stoler sterkt på JavaScript-ternær betinget snarvei i denne delen av koden, da den gir en utmerket mekanisme for bare å lage og legge til elementer hvis de ikke allerede eksisterer.

Du har kanskje også lagt merke til at vi angir en variabel for å holde innholdet i gjeldende utløsers tittelattributt, du lurer kanskje på hvorfor vi ikke bruker følgende kode i stedet:

 // legg til p hvis ikke eksisterer, oppdatere den hvis den gjør det ($ ("p # title"). lengde == 0)? $ ("

") .attr (" id "," tittel "). tekst ($ (dette) .attr (" title ")). appendTo (" div # controls "): $ (" p # tittel "). );

Årsaken til dette er at det ikke er tvetydighet om hva $ (dette) refererer til. Bruk av koden ovenfor gjør det, men det kaster feil, noe som ikke er dødelig, men det er ikke så beroligende for potensielle brukere av widgeten. Bruk av variabelen sørger bare for at disse feilene unngås. Kontrollpanelet, når det er synlig, vises som i følgende skjermbilde:

Etter mouseover blir animasjonen stoppet; vi kan starte det på nytt igjen med en mouseout event handler, som vi bør legge til neste:

 // start på mouseout $ ("a.wrapper"). live ("mouseout", funksjon (e) // skjul kontroller hvis ikke svinger på dem (e.relatedTarget == null)? null: (e.relatedTarget. id: = "kontroller")? $ ("div # kontroller"). slideUp ("slow"). fjern (): null; // utregne total kjøreavstand var totalDistance = parseInt ($ ("div # container") .bredde ()) + parseInt ($ ("div # viewer"). bredde ()); / utreise avstand venstre for å reise var distanceLeft = ($ ("div # container"). harClass ("ltr")) css ("left")) + parseInt ($ ("div # container"). bredde ())): totalDistance - (parseInt ($ ("div # viewer "). bredde ()) - (parseInt ($ (" div # container "). css (" left "))); // ny varighet er avstand venstre / hastighet) var newDuration = distanceLeft / speed; // gjenstart anim animator ($ ("div # container"), newDuration, $ ("div # container"). Attr ("klasse")); );

Igjen bruker vi jQuerys live-metode, men denne gangen overfører vi også det råbegivenhetsobjektet til vår anonyme tilbakeringingsfunksjon. Vi benytter dette objektet med en gang for å se om pekeren har flyttet til kontrollpanelet. Hvis den ikke har det, skjuler vi kontrollene, men hvis den har, gjør vi ingenting og fortsetter med å starte animasjonen på nytt. Legg merke til hvordan vi bruker en nestet ternær som tilsvarer en hvis ellers betinget.

Hovedformålet med den anonyme funksjonen er å starte animasjonen på nytt, men før vi kan gjøre det, må vi utarbeide animasjonens varighet. Vi kan ikke hardkod verdien fordi bildebeholderen har flyttet. Den opprinnelige varigheten ble satt til 1 sekund for hvert bilde, i dette eksemplet 5 sekunder. Hvis det bare er ett bilde igjen i seeren, og vi stiller animasjonen til 5 sekunder igjen, vil animasjonen fortsette markert langsommere.

Vi utarbeider først hva den totale avstanden er at billedbeholderen reiser i full animasjon. Vi utarbeider deretter hvor mye av hele avstanden som fortsatt skal reises. Vi må gjøre en annen beregning avhengig av om animasjonen skjer fra venstre til høyre eller motsatt, slik at vi igjen bruker den ternære betingede.

Hvis animasjonen foregår fra venstre til høyre, er avstanden som er igjen for å reise, den venstre stilattributten til bildebeholderen (oppnådd ved hjelp av css jQuery-metoden) lagt til bredden på bildebeholderen, trukket fra den totale avstanden. Hvis bildebeholderen beveger seg fra høyre til venstre, er imidlertid avstanden som er igjen for å reise, bredden på bildebeholderen minus den venstre stilattributtet, trukket fra den totale avstanden. Bredden og css jQuery-metodene returnerer strengverdier, så vi bruker JavaScript's parseInt-funksjon for å konvertere disse til numeriske verdier.

Den nye varigheten av animasjonen beregnes da ved å dele avstanden som er igjen for å reise med den hastigheten vi trente rett ved starten av koden. Når vi har denne figuren, kan vi deretter ringe animasjonsfunksjonen igjen i de nødvendige parametrene, slik at animasjonen starter opp igjen fra der den stoppet, i samme retning.


Endre retning

For den siste delen av skriptet kan vi legge til håndteringsprogrammer for koblingene i kontrollpanelet som brukes til å endre animasjonsretningen. Direkte etter koden vi nettopp har lagt til, skriv inn følgende kode:

 // handler for ltr knapp $ ("# ltr"). live ("klikk", funksjon () // stopp anim $ ("div # container" div # container "). removeClass (" rtl "). addClass (" ltr "); // tråkk total reiseavstand var totalDistance = parseInt ($ (" div # container "). bredde ()) + parseInt "div # viewer"). bredde ()); // trene av gjenværende avstand var distanceLeft = totalDistance - (parseInt ($ ("div # container"). css ("left")) + parseInt beholder "). bredde ()); // ny varighet er avstand venstre / hastighet) var newDuration = distanceLeft / speed; // start anim animator ($ ("div # container"), newDuration, "ltr"); );

Denne funksjonen, utløses når venstre til høyre knapp klikkes, er relativt enkel og inneholder kode som ligner på det vi allerede har brukt. Vi stopper først den nåværende animasjonen (den vil ha gjenopptatt når den besøkende beveger pekeren over kontrollpanelet), og bytt deretter på klassenavnet slik at den stemmer overens med den nye retningen. Vi utarbeider den nye animasjonsvarigheten på samme måte som vi gjorde tidligere, før vi endelig ringte vår animasjonsfunksjon igjen. Dette er bare handler for ltr-knappen; håndterer for rtl-knappen er nesten identisk, men bruker riktig beregning for motsatt retning av reisen:

 // handler for rtl-knappen $ ("# rtl"). live ("klikk", funksjon () // stopp anim $ ("div # container" div # container "). removeClass (" ltr "). addClass (" rtl "); // utregne total reiseavstand var totalDistance = parseInt ($ (" div # container "). bredde ()) + parseInt "div # viewer"). bredde ()); // utreste gjenværende avstand var distanceLeft = totalDistance - (parseInt ($ ("div # viewer"). bredde ()) - (parseInt ) .css ("left"))); // ny varighet er avstand venstre / hastighet) var newDuration = distanceLeft / speed; // start anim animator ($ ("div # container"), newDuration, "rtl"); );

Dette er nå all koden vi trenger å skrive, hvis du kjører siden i en nettleser på dette punktet, bør du oppdage at widgeten fungerer som beregnet.


Sammendrag

I denne opplæringen har vi opprettet en morsom og interaktiv widget for å vise en serie bilder og kan brukes til å vise logoer fra produsentene av produkter du selger, eller logoer av programvare du anbefaler, eller noe annet du liker. Vi fokuserte hovedsakelig på animasjons- og interaksjonsaspekter av widgeten, men også betraktet ting som å gi en grunnleggende tilbakebetaling i tilfelle JavaScript er deaktivert i nettleseren.