Costruire una Galleria Immagini con Progressive Enhancement

Chi non ama trucidare completamente il proprio sito Web con funzionalità nitide? Ma cosa succede quando i tuoi spettatori non utilizzano il browser più recente o hanno il JavaScript disattivato? Nel tutorial di oggi, imparerai come creare una galleria di immagini che funzionerà in quasi tutti gli ambienti, utilizzando tecniche di miglioramento progressivo.


introduzione

Quindi cos'è esattamente il miglioramento progressivo? Formalmente, è questo:

Il miglioramento progressivo è una strategia per il web design che enfatizza l'accessibilità, il markup semantico e il foglio di stile esterno e le tecnologie di scripting. Il miglioramento progressivo utilizza le tecnologie web in modo stratificato che consente a tutti di accedere ai contenuti e alle funzionalità di base di una pagina Web, utilizzando qualsiasi browser o connessione Internet, fornendo anche a quelli con una larghezza di banda migliore o software browser più avanzato una versione avanzata della pagina. (Wikipedia).

Il miglioramento progressivo è l'opposto di un degrado aggraziato, in cui si costruisce il sito / l'app con tutte le funzionalità, quindi si assicura che funzioni bene e funzioni in modo decente nei browser più vecchi. Con il miglioramento progressivo, getteremo una solida base per la nostra galleria di immagini che funzionerà indipendentemente da dove la guardi. Quindi, metteremo a fuoco le funzionalità e gli effetti finché non avremo una galleria di immagini di bell'aspetto e ben funzionante. Cominciamo!

Cosa stiamo dopo

Ecco cosa vogliamo finire: se tutte le suonerie e i fischietti sono accesi, potremo trascinare le nostre immagini per vederle; sarà una simulazione molto semplice di una pila di foto sul tavolino da caffè. Quando fai clic su uno di essi, si aprirà per mostrare alcuni dettagli sull'immagine. Se JavaScript è disattivato, avremo una bella griglia di immagini tra cui scegliere; cliccando su di essi ci condurrà a una pagina con una versione più grande dell'immagine e dei dettagli. Se non c'è supporto CSS, otterremo una lista brutta (ma funzionante) delle immagini.

Ecco una schermata del nostro prodotto finale:

Posa della Fondazione: POSH

Iniziamo con un semplice vecchio codice HTML semantico. Questo è il nostro fondamento, dal momento che ogni browser là fuori è in grado di analizzare l'HTML.

index.htm

     Galleria di immagini progressivamente migliorata   

Clicca su un'immagine qui sotto per vederlo!

  • 3dOcean
  • AudioJungle
  • ActiveDen
  • GraphicRiver
  • ThemeForest
  • VideoHive

Questo è tutto; roba piuttosto semplice, eh? Nessun browser che valga quel titolo dovrebbe avere un problema con esso. E questo è il nostro primo strato finito. No, non è bello, ma quello non era il nostro obiettivo: volevamo qualcosa che funzionasse ovunque, a prescindere da cosa. Alcune cose da notare su questo codice: in primo luogo, è semantica, come abbiamo detto dovrebbe essere. Potresti chiederti delle div all'interno degli oggetti della lista. Che succede con loro? Anche se iniziamo con le ossa nude, stiamo anticipando che la maggior parte dei nostri spettatori avrà JavaScript abilitato, nel qual caso avremo bisogno di quelle div. Potremmo inserirli con jQuery, ma da noi fare si aspettano che vengano utilizzati la maggior parte del tempo, è più facile codificarli. L'altra cosa da notare è che è utilizzabile. Prova a visualizzarlo in Lynx o in un altro browser di solo testo:

A proposito, le pagine collegate nel codice HTML sopra saranno disponibili nella fonte scaricabile; sono tutti simili a questo:

     Themeforest MarketPlace di Envato   

ThemeForest

ThemeForest

Offerte Themeforest: Modelli HTML, WordPress, Joomla, Siti Flash, Modelli PSD, Javascript, script PHP

Su un sito reale, lo circonderesti con il modello del tuo sito, ma è perfetto per i nostri scopi.

Vestire la struttura: CSS

Sebbene l'HTML semantico sia bello, sembra un po 'spoglio. Vestiamolo con dei CSS. Ovviamente, dobbiamo prima fare riferimento al foglio di stile:

  

Iniziamo a livellare il campo di gioco con un reset Meyer ridotto:

 / * Reset di Meyer * / html, corpo, div, h1, h2, h4, p, a, img, ul, li margine: 0; padding: 0; confine: 0; contorni: 0; font-weight: inherit; stile font: eredita; dimensione carattere: 100%; font-family: inherit; vertical-align: baseline;  / * ricorda di definire gli stili di messa a fuoco! * /: focus contorno: 0;  body line-height: 1; colore nero; sfondo: bianco;  ol, ul list-style: none;  / * END Reset di Meyer * / 

Ora dobbiamo modellare la nostra galleria per l'uso senza JavaScript. Inizieremo con alcuni elementi generali e lo stile di sfondo:

 body 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 padding: 10px; h4 font-size: 20px; padding-bottom: 10px;

Ora ci occuperemo della nostra rubrica e degli elementi della lista.

 #container h1 padding: 10px;  #images li float: left; sfondo: #ececec; border: 1px solid #ccc; margin: 10px; larghezza: 256 px; imbottitura: 10px; overflow: nascosto;  #images li div width: 512px; overflow: hidden;  #images li a float: left;  #images li div.info width: 246px; riempimento: 0 0 0 10 px; float: sinistra;  

Noterai che abbiamo impostato una larghezza sui nostri elementi della lista. Dobbiamo farlo per la nostra funzionalità JavaScript; questo è anche il motivo per cui l'overflow: hidden è impostato. Questo è facile nel nostro caso, perché ho reso tutte le immagini della stessa larghezza. Se la tua è di larghezza diversa, probabilmente dovrai impostare la larghezza per ogni elemento della lista con JavaScript. Funzionerà perché la versione solo CSS non richiede la larghezza. Il div direttamente all'interno della nostra voce di elenco (che racchiude tutto il contenuto) è largo 512 px, con overflow nascosto. Abbiamo spostato la nostra ancora a sinistra in modo da poter spostare il div.info a sinistra accanto, come si vede più avanti.

Quindi, ecco i frutti delle nostre fatiche finora:

Torneremo ai CSS in un po '; ma ora, passiamo al JavaScript!

Aggiunta della funzionalità: JavaScript

Utilizzeremo jQuery qui; quindi inizia importandolo dalla rete CDN di Google. Avremo anche bisogno della libreria jQueryUI. Potremmo prenderlo anche da Google, ma non abbiamo bisogno dell'intera libreria. Ho scaricato una copia dal sito jQueryUI, con solo il nucleo e i componenti trascinabili, che è tutto ciò di cui abbiamo bisogno. Puoi fare quello che preferisci.

   

Prima di iniziare la codifica, stabiliamo cosa dobbiamo fare.

  • L'h1 che abbiamo codificato fornisce istruzioni per la versione non JavaScript. Lo rimuoveremo e aggiungeremo istruzioni diverse.
  • Dobbiamo configurare il trascinamento sugli elementi della lista; aggiungeremo un tocco di divertimento: quando l'utente rilascia l'elemento della lista, scivolerà un po 'più in basso e rallenterà (sembra un iEffect). Come abbiamo detto prima, dovrebbe essere un po 'come una pila di foto su un tavolo.
  • Quando viene fatto clic su un elemento della lista, dovrebbe "aprirlo", raddoppiando di larghezza. Prima però, invieremo una chiamata Ajax per ottenere la pagina a cui l'utente andrebbe se JavaScript non fosse abilitato. Quindi, otterremo i valori desiderati da quella pagina e li inseriremo nella nostra voce di elenco in un div. Verificheremo questo div prima di effettuare la chiamata, quindi, se l'utente ha già fatto clic su di esso, non invieremo un'altra richiesta.

Va bene, apri un tag script e facciamo il codice!

 var imgs; $ (document) .ready (function () ); $ (window) .load (function () );

Inizieremo creando una variabile globale: una matrice degli elementi della lista (beh, sarà presto una matrice). Quindi, impostiamo i gestori di eventi per a) quando il DOM è pronto e b) al termine del caricamento della finestra. L'effetto che faremo quando verrà caricata la finestra (di cui non ti ho ancora parlato) non richiede di aspettare fino ad allora, ma penso che sarà più bello quando le immagini saranno caricate.

Ora, questo codice va nella nostra funzione document.ready:

 var drag = ; $ ( 'H1') rimuovere ().; $ ( '#') Le immagini. Accodare ('
  • Lancia le immagini intorno; se ne vedi una che ti piace, fai clic su di essa!

  • '); imgs = $ ('# images li');

    Dovrebbe essere semplice: creiamo un oggetto che manterrà alcuni dettagli sul trascinamento; quindi rimuoviamo la h1, aggiungiamo una voce di elenco con nuove istruzioni alla nostra lista e inseriamo tutti gli elementi della lista nella nostra variabile imgs.

    Ora costruiremo la nostra funzionalità di trascinamento. Davvero è così semplice:

     imgs.draggable (); 

    Ma aggiungeremo alcune opzioni. Ecco il codice; persuaditi e poi ci passeremo sopra.

     imgs.draggable (stack: group: '#images li', min: 1, start: function () $ this = $ (this); if ($ this.attr ("id") === ' istruzioni ') $ this.fadeOut (). remove (); imgs.each (function () var $ this = $ (this); if ($ this.width ()! == 256) $ this. stop (). animate (width: 256). removeClass ('top');); drag.startTime = new Date (); drag.startPos = $ this.position ();, stop: function ( ) var $ this = $ (this), in alto, a sinistra, ora; drag.endTime = new 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 = (drag.topOffset / time) .toString (); left = (drag.leftOffset / time) .toString (); $ this.animate (top: '+ =' + top, left: '+ =' + left);); 

    Abbiamo aggiunto tre proprietà al nostro oggetto opzioni trascinabili: stack, start e stop. Stack controlla lo z-index di un gruppo di oggetti e prende un oggetto con due proprietà proprie: gruppo e min. Group è un selettore jQuery; nel nostro caso, sono gli elementi della lista. Min è lo z-index minimo che ogni elemento nel gruppo può assumere. Così ora, quando si trascina un oggetto, si arriva in cima alla pila.

    La funzione di avvio viene eseguita quando inizi a trascinare un elemento. Iniziamo memorizzando nella cache $ (questo). Quindi, controlliamo se l'elemento della lista che abbiamo afferrato ha un id di "istruzioni". Se lo fa, lo svanire e rimuoverlo. Quindi, eseguiamo il loop su ciascun elemento dell'elenco e se ne troviamo uno che non sia largo 256 px, animiamo la larghezza a 256 px e rimuoviamo la classe di "top". Cosa fa 'top'? Lo modificheremo in pochi minuti, ma restituisce all'utente un feedback visivo quando fa clic su un elemento. Dopodiché, facciamo qualcosa di molto importante: impostiamo due proprietà sul nostro oggetto drag. Uno (startTime) è il momento in cui è iniziato il trascinamento e l'altro (startPos) è la posizione in cui è iniziato l'elemento. Useremo queste informazioni per creare il nostro effetto quando il trascinamento si interrompe.

    Infine, abbiamo la funzione stop, che funziona in modo prevedibile quando l'utente interrompe il trascinamento. Di nuovo, iniziamo memorizzando nella cache $ (this), oltre a creare alcune altre variabili a cui daremo dei valori in un momento. Successivamente, inseriamo il tempo di fine e la posizione in drag.endTime e drag.endPosition. Quindi calcoliamo il nostro offset di sinistra e superiore sottraendo dove eravamo da dove siamo; possiamo farlo con le proprietà superiore e sinistra che ha l'oggetto posizione. Ora per il rallentamento della logica animata: potresti diventare molto complicato con questo algoritmo, ma lo manterremo semplice. Troveremo il tempo impiegato dal trascinamento sottraendo il nostro tempo di inizio dal nostro tempo di fine; il metodo getTime restituisce il numero di millesecondi dal 1970/01/01, quindi la differenza è in millesecondi Quindi, dividiamo quel valore per 60, che ho trovato con tentativi ed errori. Con una resistenza media, questo imposta la nostra variabile temporale tra 2 e 3. Quindi dividiamo il nostro offset superiore e sinistro in base al tempo e convertiamo questi valori in stringa, salvandoli in alto ea sinistra. Infine, animiamo la voce della lista trascinata, incrementando (questo è ciò che '+ =' fa) il valore in alto o a sinistra. A questo punto, dovresti riuscire a trascinare le immagini e ottenere il nostro effetto.

    Tuttavia, facendo clic sulle immagini verrà visualizzata una nuova pagina. Quindi impostiamo il nostro gestore di eventi click.

     imgs.click (function () var $ this = $ (this); if ($ this.attr ('id') === 'istruzioni') $ this.fadeOut (). remove (); else  if ($ this.width ()! == 256) $ this.stop (). animate (width: 256). removeClass ('top'); else if (! ($ this.find (' .info '). length)) $ .ajax (url: $ this.find (' a '). attr (' href '), dataType:' html ', success: function (data) var $ d = $ (dati), testa = $ d.filter ('h1'), para = $ d.filter ('p'); $ this.children ('div'). append ('
    ') .find (". info"). append (testa, para); , errore: function () var msg = '

    Spiacenti!

    Sembra che ci sia stato un problema; non possiamo ottenere queste informazioni adesso.

    '; $ This.children ( 'div'). Append ('
    . ') .Find ( "info") html (msg); ); $ this.css ('zIndex': 8) .stop () .animate (width: 512) .addClass ('top') .siblings (). removeClass ('top') .stop (). animate (width: 256) .filter (function () return $ (this) .css ('zIndex') === '8'). css ('zIndex': 7); return false; );

    Procedura operativa standard oggi: inizia con il caching $ (questo). Ancora una volta, controlliamo l'id delle istruzioni; se è lì, dissolviamo e rimuoviamo l'oggetto. Se non è lì, controlliamo la larghezza dell'elemento: se non è 256px, significa che questo elemento è già stato cliccato, quindi animiamo la larghezza fino a 256 e rimuoviamo la nostra classe superiore (sì, ci arriveremo ). Se l'elemento è largo 256 px, controlliamo un elemento figlio con la classe di informazioni. Possiamo fare questo chiamando il metodo find sull'elemento, passare il selettore che stiamo cercando e ottenere la proprietà length. Se questo elemento non esiste, il risultato sarà 0, che è un valore falso, quindi lo racchiudiamo tra parentesi e usiamo a! per cambiare il booleano. Ora, se non ci sono elementi figlio con una classe di informazioni, entreremo in questo blocco, che è la nostra chiamata Ajax.

    $ .ajax () accetta un parametro oggetto e utilizzeremo quattro proprietà: url, datatype, success e error. Url e datatype sono ovvi: semplicemente troviamo l'ancora nella nostra voce di lista e impostiamo url al suo href; il nostro tipo di dati è html. Se la nostra chiamata ajax ha esito positivo, prenderemo i dati che otteniamo, ovvero l'intero contenuto HTML della pagina, e lo trasformeremo in un oggetto jQuery. Quindi, possiamo filtrare l'intestazione e il paragrafo che sappiamo di avere lì. Quindi otteniamo semplicemente il div all'interno della nostra voce di elenco, aggiungiamo un div.info e aggiungiamo l'intestazione e il paragrafo a quello. Se la nostra richiesta non riesce, mostreremo un messaggio di errore con un processo simile, utilizzando la funzione di errore. Dopo la nostra chiamata ajax, vogliamo eseguire alcuni stili e animazioni sulla nostra voce di elenco. Per prima cosa, vogliamo impostare z-index su 8, o qualsiasi numero maggiore del numero di elementi trascinabili che abbiamo. Quindi vogliamo interrompere tutte le animazioni correnti su questo elemento dell'elenco e animare la larghezza a 512 pixel. Infine, aggiungeremo quella classe superiore. Successivamente, otteniamo tutti i fratelli, che sono gli altri elementi della lista. Interrompiamo qualsiasi animazione su di loro e quindi li animiamo a 256 px di larghezza. Infine, filtreremo solo gli elementi con uno z-index di 8 e cambieremo il loro z-index in 7. Ciò consente alla voce di elenco attualmente tratteggiata di venire in cima. Alla fine, restituiamo false, quindi restiamo sulla nostra pagina corrente (perché anche se questa è una funzione di clic su un elemento della lista, molto probabilmente gli utenti faranno clic sulla nostra immagine ancorata all'interno dell'elemento della lista).

    Questo è il nostro gestore di clic; è rimasto solo un pezzo di JavaScript. Se dai al nostro esempio una prova ora, vedrai che funziona ... un po '. Ogni volta che fai clic su un elemento dell'elenco per aprirlo, si apre, ma noterai un problema piuttosto sfuggente. È perché gli elementi della lista sono flottati a sinistra; prendiamocene cura nel nostro gestore pronto per le finestre.

     $ (window) .load (function () var $ w = $ (window); imgs.css (position: 'absolute', left: $ w.width () / 2 - imgs.width (), alto: $ w.height () / 2- imgs.height ()); for (var i = 0; imgs [i]; i ++) $ (imgs [i]). animate (left: '+ =' + Math.random () * 150, in alto: '+ =' + Math.random () * 150);); 

    Se hai seguito abbastanza bene fino ad ora, non ti tiri indietro: utilizziamo semplicemente il metodo css di jQuery per impostare il posizionamento su assoluto e impilare tutte le immagini in modo che i loro bordi destro siano allineati al centro del viewport, e il loro i bordi inferiori sono allineati al centro verticale. Quindi usiamo un ciclo for per ricorrere su ogni elemento dell'elenco e lo animiamo casualmente verso destra e verso il basso. Questo crea l'effetto di una pila di immagini che vengono disperse.

    Quindi è tutto per il JavaScript! Ora, quando un utente carica la pagina, dovrebbe vedere qualcosa di simile a questo (dopo l'animazione):

    Tocchi finali: CSS3

    Potremmo finire lì, ma vogliamo premiare chi usa i browser lungimiranti, quindi è di nuovo sul CSS per pochi minuti. E sì, guarderemo la classe più alta.

    La prima cosa che faremo è aggiungere gli angoli arrotondati al selettore #images li.

     border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; 

    Quindi la classe superiore, che elenca gli elementi solo quando sono "aperti", assomiglia a questo:

     .top box-shadow: 0 0 10px # 000; -moz-box-shadow: 0 0 10px # 000; -webkit-box-shadow: 0 0 30px # 000;  

    Niente di incredibilmente elaborato, ma comunque alcune belle rifiniture.

    Commenti di chiusura

    Bene, è tutto. Ora dovremmo avere una galleria di immagini che funziona in modo decente senza CSS o JavaScript, ma ne sfrutta al massimo le risorse laddove tali tecnologie sono disponibili. Quindi, come miglioreresti la nostra galleria? Sentiamolo nei commenti!