Hvem elsker ikke å helt lure ut deres nettside med ryddige funksjoner? Men hva skjer når seerne ikke bruker den nyeste nettleseren, eller de har JavaScript slått av? I dagens veiledning lærer du hvordan du lager et bildegalleri som vil fungere i nesten alle miljøer, ved hjelp av progressive forbedringsmetoder.
Så hva er progressiv forbedring? Formelt er det dette:
Progressiv forbedring er en strategi for webdesign som legger vekt på tilgjengelighet, semantisk markering og ekstern stilark og skriptingsteknologi. Progressiv forbedring bruker webteknologi på en lagdelt måte som gjør det mulig for alle å få tilgang til det grunnleggende innholdet og funksjonaliteten til en nettside, ved hjelp av en hvilken som helst nettleser eller Internett-tilkobling, samtidig som de gir bedre båndbredde eller mer avansert nettleser en forbedret versjon av siden. (Wikipedia).
Progressiv forbedring er motsatt av grasiøs nedbrytning, hvor du bygger ditt nettsted / app med alle funksjonene, og sørg for at det ser bra ut og fungerer greit i eldre nettlesere. Med progressiv forbedring legger vi et solid fundament for vårt bildegalleri som vil fungere uansett hvor du ser det. Da lagrer vi øye-godteri og funksjonalitet til vi har et godt, velfungerende bilgalleri. La oss begynne!
Her er det vi vil ende opp med: hvis alle klokkene og fløyter er slått på, kan vi dra våre bilder rundt for å se dem; det vil være en veldig grunnleggende simulering av en stabel med bilder på salongbordet ditt. Når du klikker på en, vil den glide åpen for å avsløre noen detaljer om bildet. Hvis JavaScript er slått av, har vi et fint rutenett for å velge mellom; ved å klikke på dem, tar vi oss til en side med en større versjon av bildet og detaljene. Hvis det ikke er CSS-støtte, får vi en stygg (men arbeider) liste over bildene.
Her er et skjermbilde av vårt endelige produkt:
Vi starter med noen vanlig gammel semantisk HTML. Dette er vårt fundament, siden alle nettlesere der ute er gode til å analysere HTML.
Progressivt forbedret bildegalleri Klikk på et bilde under for å se det!
Det er det; ganske grunnleggende ting, eh? Ingen nettleser verdt den tittelen skal ha et problem med det. Og dette er vårt ferdige første lag. Nei, det er ikke pent, men det var ikke vårt mål: Vi ønsket noe som vil fungere overalt, uansett hva. Noen ting å legge merke til om denne koden: For det første er det semantisk, som vi sa det burde være. Du lurer kanskje på divsene i listepostene. Hva skjer med dem? Selv om vi starter med de bare beinene, forventer vi at de fleste av våre seere vil ha JavaScript aktivert, i så fall trenger vi de divene. Vi kunne sette dem inn med jQuery, men siden vi gjøre Forvent at de skal brukes mesteparten av tiden, det er lettere å kode hardt inn. Den andre tingen å legge merke til er at den er brukbar. Prøv å vise den i Lynx, eller en annen nettleser som bare er i tekst:
Forresten, sidene som er koblet til i HTML-koden ovenfor, vil være tilgjengelige i nedlastbar kilde; de ligner alle på dette:
Themeforest MarketPlace av Envato Themeforest
Themeforest tilbyr: HTML-maler, WordPress, Joomla, Flash-sider, PSD-maler, Javascript, PHP-skript
På et ekte nettsted, vil du omgjøre dette med nettstedet mal, men det er bare bra for våre formål.
Selv om semantisk HTML er fint, ser det litt ut. La oss kle det med noen CSS. Selvfølgelig må vi først referere stilarket:
Vi planlegger nivået først med en tilbaketrukket Meyer reset:
/ * Meyer Tilbakestill * / html, kropp, div, h1, h2, h4, p, a, img, ul, li margen: 0; polstring: 0; grense: 0; oversikt: 0; font-weight: arv; font-style: arv; skriftstørrelse: 100%; font-familie: arv; vertikaljustering: basislinje; / * Husk å definere fokus stiler! * /: fokus disposisjon: 0; kropp linjehøyde: 1; farge svart; bakgrunn: hvit; ol, ul listestil: ingen; / * End Meyer Reset * /
Nå må vi stille inn vårt galleri for bruk uten JavaScript. Vi begynner med noen generelle elementer og bakgrunnsstyling:
kropp font: 13px / 1.5 'Helvetica Neue', Arial, 'Liberation Sans', FreeSans, sans-serif; / * <-- from 960.gs text.css */ background: #36b4dd; h1 font-size: 30px; #container > h1 polstring: 10px; h4 font-size: 20px; padding-bottom: 10px;
Nå tar vi vare på våre overskrifter og listeposter.
#container h1 polstring: 10px; #images li float: left; bakgrunn: #ececec; grense: 1px solid #ccc; margin: 10px; bredde: 256px; polstring: 10px; overløp: skjult; #images li div width: 512px; flow: hidden; #images li a float: left; #images li div.info width: 246px; polstring: 0 0 0 10px; float: venstre;
Du vil legge merke til at vi har satt en bredde på listelementene våre. Vi må gjøre det for vår JavaScript-funksjonalitet; det er også hvorfor overløp: skjult er satt. Dette er lett i vårt tilfelle, fordi jeg har laget alle bildene i samme bredde. Hvis dine er forskjellige bredder, må du sannsynligvis sette bredden for hvert listepost med JavaScript. Det vil fungere fordi CSS-versjonen ikke krever bredden. Diven som ligger direkte innenfor vårt listepost (som bryter alt innholdet) er 512px bredt, med overlap gjemt. Vi har floppet vårt anker til venstre slik at vi kan flyte div.info til venstre ved siden av det, som du ser videre på.
Så her er frukten av vårt arbeid så langt:
Vi kommer tilbake til CSS på litt; men nå, la oss gå til JavaScript!
Vi bruker jQuery her; så start med å importere det fra Googles CDN. Vi trenger også jQueryUI-biblioteket. Vi kan også få det fra Google, men vi trenger ikke hele biblioteket. Jeg har lastet ned en kopi fra jQueryUI-siden, med bare kjerne og de trekkbare komponentene, som er alt vi trenger. Du kan gjøre det du foretrekker.
Før vi begynner koding, la oss bestemme hva vi trenger å gjøre.
Ok, åpne et skript og la oss kode!
var imgs; $ (dokument) .ready (funksjon () ); $ (vindu) .load (funksjon () );
Vi starter med å opprette en global variabel: en rekke listeposter (vel, det vil snart være en matrise). Deretter setter vi opp hendelsesbehandlere for a) når DOM er klar, og b) når vinduet er ferdig lastet. Effekten vi skal gjøre når vinduet laster (som jeg ikke har fortalt deg om ennå) krever ikke at vi venter til da, men jeg tror det blir bedre når bildene er lastet.
Nå går denne koden i vår document.ready funksjon:
var dra = ; $ ( 'H1') fjerne (.); $ ( '# Bilder'). Append ('
Bør være grei: Vi lager et objekt som vil holde noen detaljer om uttrekking; da fjerner vi h1, legger til en liste med nye instruksjoner til listen vår, og legger alle listepostene i vår imgs-variabel.
Nå bygger vi vår slepefunksjonalitet. Virkelig er det så enkelt som dette:
imgs.draggable ();
Men vi skal legge til noen få alternativer. Her er koden; persue det selv og da vil vi spasere gjennom den.
imgs.draggable (stack: group: '#images li', min: 1, start: funksjon () $ this = $ (dette); hvis ($ this.attr ("id") === ' instruksjoner ') $ this.fadeOut (). fjern (); imgs.each (funksjon () var $ this = $ (dette); hvis ($ this.width ()! == 256) $ dette. stop (): drag.startPos = $ this.position ();, stop: function ((bredde: 256). FjernClass ('top');); drag.startTime = nytt Dato ) var $ this = $ (dette), topp, venstre, tid; drag.endTime = nytt Date (); drag.endPos = $ this.position (); drag.leftOffset = drag.endPos.left - drag.startPos .left; drag.topOffset = drag.endPos.top - drag.startPos.top; time = (drag.endTime.getTime () - drag.startTime.getTime ()) / 60; top = (dra.topOffset / tid) .toString (); left = (drag.leftOffset / time) .toString (); $ this.animate (top: '+ =' + topp, venstre: '+ =' + venstre););
Vi har lagt til tre egenskaper i vårt trekkbare alternativobjekt: stable, start og stopp. Stack kontrollerer z-indeksen for en gruppe objekter, og tar et objekt med to egenskaper av seg selv: gruppe og min. Gruppen er en jQuery-velger; i vårt tilfelle er det listepostene. Min er den minste z-indeksen noen elementer i gruppen kan ta. Så nå, når du drar et element, kommer det til toppen av haugen.
Start-funksjonen kjøres når du begynner å dra et element. Vi starter med å cache $ (dette). Deretter sjekker vi for å se om listen elementet vi grep har et ID-instruksjon. Hvis det gjør det, forsvinner vi det og fjerner det. Deretter løper vi over hvert listeelement, og hvis vi finner noen som ikke er 256px bred, animerer vi bredden til 256px og fjerner klassen "topp". Hva er 'topp'? Vi stiler det om noen få minutter, men det gir bare brukeren visuell tilbakemelding når de klikker på et element. Deretter gjør vi noe veldig viktig: vi setter to egenskaper på vårt dragobjekt. One (startTime) er den tiden draget startet, og den andre (startPos) er posisjonen som varen startet på. Vi bruker denne informasjonen til å skape vår effekt når draringen stopper.
Til slutt har vi stoppfunksjonen, som forutsigbar kjører når brukeren slutter å dra. Igjen begynner vi å cache $ (dette), samt å skape noen andre variabler, vi gir verdier til i et øyeblikk. Deretter setter vi sluttiden og posisjonen inn i drag.endTime og drag.endPosition. Deretter beregner vi vår venstre og toppforskyvning ved å trekke fra hvor vi var fra hvor vi er; Vi kan gjøre dette med topp- og venstre egenskaper som posisjonsobjektet har. Nå for å redusere animasjonslogikken: Du kan bli svært komplisert med denne algoritmen, men vi skal bare holde det enkelt. Vi finner den tiden draen tok ved å trekke vår starttid fra vår endTime; GetTime-metoden returnerer antall millesekunder siden 1970/01/01, så forskjellen er i millesekunder. Da deler vi den verdien med 60, som jeg kom opp med gjennom prøving og feiling. Med en gjennomsnittlig dra, setter dette vår tidsvariabel et sted mellom 2 og 3. Da deler vi vår topp og offset etter tid, og konverterer disse verdiene til streng, og lagrer dem i topp og venstre. Til slutt, animerer vi det slepede listeposten, øker (det er hva '+ =' gjør) verdien ved toppen eller til venstre. På dette tidspunktet bør du kunne trekke bildene rundt og få vår effekt.
Men ved å klikke på bildene kommer du til en ny side. Så la oss sette opp vår klikkhendelseshåndterer.
imgs.click (funksjon () var $ this = $ (dette); hvis ($ this.attr ('id') === 'instruksjoner') $ this.fadeOut (). remove (); else if ($ this.width ()! == 256) $ this.stop (). animate (bredde: 256). removeClass ('top'); annet hvis (! ($ this.find (' .info '). lengde)) $ .ajax (url: $ this.find (' a '). attr (' href '), dataType:' html ', suksess: funksjon (data) var $ d = $ (data), hode = $ d.filter ('h1'), para = $ d.filter ('p'); $ this.children ('div').') .find (". info"). legge til (hode, para); , feil: funksjon () var msg = 'Oops!
Det ser ut til at det har vært et problem; Vi kan ikke få denne informasjonen akkurat nå.
'; $ This.children ( 'div'). Append ('. ') .Finn ( "info") html (msg); ); $ this.css ('zIndex': 8) .stop () .animate (width: 512) .addClass ('top') .siblings (). removeClass ('top') .stop (). animere (bredde: 256) .filter (funksjon () return $ (dette) .css ('zIndex') === '8'). css ('zIndex': 7); returnere false; );
Standard operasjonsprosedyre i dag: Begynn med å cache $ (dette). Igjen, vi sjekker for id av instruksjoner; hvis det er der, vi fade ut og fjerne elementet. Hvis det ikke er der, kontrollerer vi elementets bredde: Hvis det ikke er 256px, betyr det at dette elementet allerede er klikket, så vi animerer bredden ned til 256 og fjerner vår toppklasse (ja, vi kommer dit ). Hvis elementet er 256px bredt, ser vi etter et barnelement med klassen av info. Vi kan gjøre dette min ringer finnmetoden på elementet, passere i selgeren vi leter etter, og få lengden på eiendommen. Hvis dette elementet ikke eksisterer, blir resultatet 0, som er en falsk verdi, så vi pakker det i parentes og bruker en! å bytte boolsk. Nå, hvis det ikke er noen barnelementer med en klasse med info, kommer vi inn i denne blokken, som er vårt ajax-anrop.
$ .ajax () tar en objektparameter, og vi bruker fire egenskaper: URL, datatype, suksess og feil. Url og datatype er åpenbare: vi finner bare ankeret i vår liste element og sett url til sin href; Datatypen vår er html. Hvis vårt ajax-anrop lykkes, tar vi dataene vi får, som er hele HTML-innholdet på siden, og gjør det til et jQuery-objekt. Deretter kan vi filtrere ut overskriften og avsnittet som vi vet at vi har der. Da får vi bare div i vår liste element, legger til div.info, og legger til overskriften og avsnittet til det. Hvis vår forespørsel mislykkes, viser vi en feilmelding ved hjelp av en lignende prosess, ved hjelp av feilfunksjonen. Etter vår ajax-samtale, ønsker vi å utføre noen styling og animasjon på vår liste element. Først vil vi sette z-indeksen til 8, eller et hvilket som helst tall som er høyere enn antall trekkbare elementer vi har. Da vil vi stoppe alle nåværende animasjoner på dette listeposten og animere bredden til 512px. Til slutt legger vi til toppklassen. Deretter får vi alle søsken, som er de andre listepostene. Vi stopper animasjonen på dem og animerer dem til 256px bred. Til slutt vil vi bare filtrere ut elementene med en z-indeks på 8 og endre deres z-indeks til 7. Dette gjør det mulig for den nåværende cliked-listen å komme over toppen. På slutten returnerer vi falske, så vi holder oss på vår nåværende side (fordi selv om dette er en klikkfunksjon på en liste element, vil brukerne mest sannsynlig klikke på vårt ankerinnpakket bilde inne i listeposten).
Så det er vår klikkbehandler; bare ett stykke JavaScript igjen. Hvis du gir vårt eksempel et forsøk nå, ser du det fungerer ... slags. Når du klikker på et listeelement for å åpne det, åpnes det, men du ser et ganske skittent problem. Det er fordi listepostene er floated til venstre; la oss ta vare på det i vår vindu klare handler.
$ (vindu) .load (funksjon () var $ w = $ (vindu); imgs.css (posisjon: 'absolutt', venstre: $ w.width () / 2 - imgs.width $ w.height () / 2- imgs.height ()) for (var i = 0; imgs [i]; i ++) $ (imgs [i]). animate (left: '+ =' + Math.random () * 150, topp: '+ =' + Math.random () * 150););
Hvis du har fulgt ganske bra så langt, vil du ikke flinke her: vi bruker bare jQuery's css-metode for å sette posisjoneringen til absolutt og stable alle bildene, slik at deres høyre kanter er justert til midten av visningsporten, og deres Bunnkanter er justert til den vertikale midten. Deretter bruker vi en for-løkke til å rekursere over hver liste element og tilfeldig passe den rett og ned. Dette skaper effekten av en stabel bilder som er spredt.
Så det er det for JavaScript! Nå, når en bruker laster inn siden, bør de se noe slikt (etter animasjon):
Vi kan ende der, men vi vil belønne de som bruker fremtidsrettet nettlesere, så det er tilbake til CSS i noen få minutter. Og ja, vi vil se på toppklassen.
Det første vi skal gjøre er å legge avrundede hjørner til velgeren #images li.
border-radius: 5 px; -moz-border-radius: 5 px; -webkit-border-radius: 5 px;
Deretter ser toppklassen, hvilke listeposter bare når de er 'åpne', slik ut:
.topp boks-skygge: 0 0 10px # 000; -moz-boks-skygge: 0 0 10px # 000; -webkit-boks-skygge: 0 0 30px # 000;
Ingenting utrolig fancy, men noen fine raffinementer likevel.
Vel, det er det. Vi bør nå ha et bildegalleri som fungerer anstendig uten CSS eller JavaScript, men tar full nytte av dem der teknologiene er tilgjengelige. Så, hvordan ville du forbedre vårt galleri? La oss høre det i kommentarene!