Spotlight Sticky vincolati con jQuery

A settimane alterne, daremo un'occhiata ultra focalizzata a un effetto interessante, plug-in, hack, libreria o anche una tecnologia elegante. Quindi tenteremo di decostruire il codice o creare un piccolo progetto divertente con esso.

Oggi daremo un'occhiata a un plug-in che implementa un effetto piuttosto accurato: è piuttosto difficile da spiegare in una frase, quindi puoi anche fare clic sul pulsante Continua per iniziare dopo il salto.


Una parola dall'autore

Come sviluppatori web, abbiamo accesso a una quantità impressionante di codice precostruito, che si tratti di un piccolo frammento o di un quadro completo. A meno che tu non stia facendo qualcosa di incredibilmente specifico, è probabile che ci sia già qualcosa di precompilato da sfruttare. Sfortunatamente, molte di queste offerte stellari languiscono nell'anonimato, specialmente per la folla non-hardcore.

Questa serie cerca di correggere questo problema introducendo del codice veramente ben scritto, utile - sia esso un plugin, un effetto o una tecnologia per il lettore. Inoltre, se è abbastanza piccolo, tenteremo di decostruire il codice e capire come lo fa voodoo. Se è molto più grande, cercheremo di creare un mini progetto con esso per imparare le corde e, si spera, capire come utilizzarlo nel mondo reale.


Presentazione di stickyFloat

Ecco alcune informazioni rapide:

  • Genere: Collegare
  • Tecnologia: JavaScript [Costruito sulla libreria jQuery]
  • Funzione: Contenuti mobili solo all'interno dei limiti dei confini del genitore
  • Homepage del plugin: Qui

Il problema

In molti casi, è necessario che il contenuto sia mobile mentre si scorre, ma solo all'interno del suo genitore.

Il contenuto mobile come utente scorre il resto della pagina è un gioco da ragazzi. Non è necessario JavaScript - puoi farlo semplicemente con i vecchi CSS. Slap a posizione: fissa dichiarazione su di esso e boom !, hai un contenitore che viene corretto in una posizione specifica nella pagina - è fluttuante nella pagina per essere più colloquiale.

Ma ammettiamolo, non funziona con ogni layout. Potresti pianificare un po 'più avanti e posizionarlo sulla pagina in modo che non interferisca mai con elementi importanti, ma non sarebbe né completamente infallibile né riutilizzabile altrove senza modifiche estese.

In questi casi, è necessario che il contenuto sia mobile mentre si scorre, ma solo all'interno del suo genitore.. Se ti stai chiedendo, sì, questa funzionalità è una variante di quella che Andrew ti ha mostrato nel tutorial della settimana scorsa, che è il modo in cui ho avuto modo di conoscere questo plugin.

Come si troverà nello sviluppo web, proprio come il calcolo multivariabile, ci sono spesso un numero di soluzioni per ogni problema dato. Diamo un'occhiata a una di quelle soluzioni alternative.


Decostruire la logica

La logica generale o il flusso di lavoro della spina è in realtà piuttosto semplice. Lascia che ti mostri. Tieni presente che mi riferirò all'elemento che deve essere fluttuato come appiccicoso da ora in poi.

Ma prima di iniziare, ecco un rapido mockup per mostrare la gerarchia:

L'intera logica del plugin può essere ridotta a:

  • Calcola la posizione corrente dell'elemento adesivo genitore, relativo al documento. Contrassegnato come 1 nell'immagine.
  • Ottieni anche l'altezza del genitore - Quindi sapremo quando smettere di fluttuare quando supereremo il genitore. Contrassegnato come 2.
  • Calcola fino a che punto la pagina è stata scorsa verso il basso - Per scoprire se stiamo guardando il genitore - per vedere se siamo nel raggio d'azione. Nell'immagine sopra, la linea orizzontale indica la parte superiore ipotetica della finestra corrente. In questo caso, questo valore sarà la distanza tra i punti segnati come 3.
  • Usando i due valori che abbiamo calcolato sopra, possiamo scoprire molto rapidamente se l'appiccicoso deve essere riposizionato in modo appropriato.

Se sei confuso, non essere. Ad esempio, diamo un'occhiata ad alcuni numeri di esempio:

  • Il genitore appiccicoso è presente 10px dalla parte superiore della pagina.
  • Il genitore è 100px alto.
  • La pagina è stata scorsa 50px in uno scenario e 150px nell'altro.

Quindi, sulla base di queste informazioni di cui sopra, è possibile dedurre che

Nello scenario uno - l'appiccicoso dovrebbe essere ridirato adeguatamente. Perché? La pagina è stata scorsa di 10px dall'alto - 10 proviene dalla pagina stessa mentre il resto proviene dal genitore appiccicoso. Pertanto, il genitore è visibile nella finestra principale.

Nello scenario due - l'appiccicoso può essere lasciato solo. Del 150px, 10 proviene dalla pagina, 100 dall'elemento genitore e il resto è occupato dal resto dell'elemento della pagina. Ciò implica che l'utente ha passato il genitore e non abbiamo bisogno di fare nulla.

Se sei ancora sfocato a questo punto, non preoccuparti. Spiegherò un po 'di più mentre percorro la fonte.


Decostruire la fonte

La fonte spogliata dei commenti è lunga solo una trentina di righe. Come sempre, passeremo attraverso il codice e spiegheremo cosa fa ogni linea.

Ecco la fonte, per riferimento.

 $ .fn.stickyfloat = function (options, lockBottom) var $ obj = this; var parentPaddingTop = parseInt ($ obj.parent (). css ('padding-top')); var startOffset = $ obj.parent (). offset (). top; var opts = $ .extend (startOffset: startOffset, offsetY: parentPaddingTop, durata: 200, lockBottom: true, opzioni); $ obj.css (position: 'absolute'); if (opts.lockBottom) var bottomPos = $ obj.parent (). height () - $ obj.height () + parentPaddingTop; se (bottomPos < 0 ) bottomPos = 0;  $(window).scroll(function ()  $obj.stop(); var pastStartOffset = $(document).scrollTop() > opts.startOffset; var objFartherThanTopPos = $ obj.offset (). top> startOffset; var objBiggerThanWindow = $ obj.outerHeight () < $(window).height(); if( (pastStartOffset || objFartherThanTopPos) && objBiggerThanWindow ) var newpos = ($(document).scrollTop() -startOffset + opts.offsetY ); if ( newpos > bottomPos) newpos = bottomPos; if ($ (document) .scrollTop () < opts.startOffset ) newpos = parentPaddingTop; $obj.animate( top: newpos , opts.duration );  ); ;

È ora di vedere cosa fa realmente. Presumo che tu abbia una conoscenza abbastanza basilare di JavaScript.

 $ .fn.stickyfloat = function (options, lockBottom) ;

Passo 1 - Il wrapper generico per un plugin jQuery. Come probabilmente sai, opzioni è un oggetto che contiene opzioni assortite per configurare il comportamento del plugin. lockBottom, interessante, specifica se la funzionalità che vogliamo è attivata o meno. Lo lasceremo acceso.

 var $ obj = this;

Passo 2 - Mantieni un riferimento all'elemento passato. In questo contesto, Questo punta all'elemento DOM che corrisponde al selettore passato. Ad esempio, se sei passato #menu, Questo punta all'elemento con quell'ID.

 var parentPaddingTop = parseInt ($ obj.parent (). css ('padding-top'));

Passaggio 3 - Questo è solo per appianare l'effetto è l'elemento genitore ha un grande padding. Se è così, questo includerà il padding nel calcolo.

 var startOffset = $ obj.parent (). offset (). top;

Passaggio 4 - Calcoliamo la posizione del genitore rispetto al documento usando il compensare metodo jQuery. Lavoriamo attraverso il DOM usando il genitore metodo. Noi $ obj dal momento che abbiamo già memorizzato nella cache l'appiccicoso. Accedi alla documentazione dell'API jQuery se non hai familiarità con questi metodi.

In questo caso, la distanza dalla cima è sufficiente, quindi acquisiremo quel valore da soli.

 var opts = $ .extend (startOffset: startOffset, offsetY: parentPaddingTop, durata: 200, lockBottom: true, opzioni);

Passaggio 5 - Una porzione piuttosto generica del processo di sviluppo del plugin jQuery. Fondamentalmente ci uniamo alle opzioni passate insieme ad alcuni preset per ottenere un set finale di opzioni che è usato in tutto il codice. Tieni presente che i parametri passati hanno sempre la precedenza sui valori predefiniti.

 $ obj.css (position: 'absolute');

Passaggio 6 - L'effetto in questione verrà creato manipolando l'elemento superiore Valore CSS quindi andremo avanti e imposteremo la sua posizione in assoluto nel caso in cui non sia già stato impostato in quel modo.

 if (opts.lockBottom) var bottomPos = $ obj.parent (). height () - $ obj.height () + parentPaddingTop; se (bottomPos < 0 ) bottomPos = 0; 

Passaggio 7 - Come notato sopra, il lockBottom opzione specifica se l'effetto in questione funziona o meno. Se abilitato, possiamo iniziare a calcolare. Quello che stiamo calcolando è il punto limite oltre il quale non avremmo bisogno di riposizionare l'appiccicoso.

Naturalmente, puoi procedere semplicemente calcolando l'altezza del genitore, ma l'effetto sarà non raffinato. Avrai bisogno di prendere in considerazione l'altezza dello stesso appiccicoso lungo eventuali paddings sul genitore stesso.

 $ (finestra) .scroll (function () // Un sacco di codice)

Passaggio 8 - Colleghiamo il nostro codice, all'interno di una funzione anonima, alle finestre ' scorrere evento. Certo, questo non è il modo più efficiente per procedere, ma lo ignoreremo per ora.

 $ Obj.stop ();

Passaggio 9 - Il primo ordine della parola è di interrompere tutte le animazioni in esecuzione sull'elemento appiccicoso. Il Stop il metodo si prende cura di questo.

 var pastStartOffset = $ (document) .scrollTop ()> opts.startOffset; var objFartherThanTopPos = $ obj.offset (). top> startOffset; var objBiggerThanWindow = $ obj.outerHeight () < $(window).height();

Passaggio 10 - Queste tre variabili contengono valori che utilizzeremo un po 'più tardi.

  • pastStartOffset controlla se abbiamo oltrepassato il limite superiore dell'elemento genitore. Ricorda, abbiamo usato il compensare metodo per scoprire lo spazio tra l'elemento genitore e il documento. Otteniamo fino a che punto sei sceso usando il scrollTop metodo. Questa è la distanza tra la parte superiore del documento e la parte superiore della finestra corrente.
  • objFartherThanTopPos controlla se l'appiccicoso si trova nella sua posizione predefinita - nella parte superiore del suo genitore. Se abbiamo oltrepassato il superiore del genitore, non vogliamo che fluttui fuori.
  • objBiggerThanWindow controlla se l'altezza totale del sticky è maggiore della dimensione della finestra. Se è così, non ha senso manipolare l'elemento appiccicoso.
 if ((pastStartOffset || objFartherThanTopPos) && objBiggerThanWindow) // Altro codice

Passaggio 11 - Qui è dove il plugin calcola se dobbiamo manipolare l'elemento appiccicoso. Cosa fa la linea sopra:

  • Controlla se l'utente sta scorrendo Esattamente nell'intervallo dell'elemento genitore. Verifichiamo se l'utente è al di sotto del limite superiore del genitore o in alternativa se l'appiccicoso è in alto.
  • Come indicato sopra, procediamo solo se l'appiccicoso è più piccolo della dimensione della finestra.

Procediamo solo se tutti e due di queste condizioni sono soddisfatte.

 var newpos = ($ (document) .scrollTop () -startOffset + opts.offsetY);

Passaggio 12 - Questa linea definisce una variabile, newPos, che specifica la posizione a cui deve essere animato l'elemento appiccicoso. Come avrai notato, il calcolo è abbastanza semplice se tenga presente l'immagine sopra. Scopri la distanza a scorrimento, aggiungi il padding superiore del genitore e infine sottrai la distanza tra il documento e il genitore - il punto di partenza. Questo ti dà la distanza, in pixel, tra la parte superiore dell'elemento genitore e il punto all'interno, dove deve essere posizionato l'appiccicoso.

 if (newpos> bottomPos) newpos = bottomPos;

Passaggio 13 - Se siamo passati oltre il limite inferiore dell'elemento genitore, non c'è bisogno di manipolare ulteriormente le cose. Blocca la sua posizione lì.

 if ($ (document) .scrollTop () < opts.startOffset ) newpos = parentPaddingTop;

Passaggio 14 - Se abbiamo scostato sopra il limite superiore del genitore, tienilo bloccato lì in modo che non si muova più in alto.

 $ obj.animate (top: newpos, opts.duration);

Passaggio 15 - Tutto fatto! Semplicemente animiamo l'elemento appiccicoso che passa nel necessario superiore valore insieme alla durata dell'effetto usando il animare metodo jQuery.


uso

Come probabilmente hai dedotto a questo punto, l'utilizzo è come questo:

 $ ('# menu'). stickyfloat (duration: 500);>

Invece di spiegare il mini-progetto di esempio, come l'ultima volta, ho deciso invece di costruirlo e darti il ​​codice.

Ecco le parti rilevanti della demo, il resto è boilerplate:

L'HTML

 
Menu appiccicoso
Volevo scrivere qualcosa di incredibilmente, sfacciatamente spiritoso qui. Non sono riuscito. :(
Sì, ti seguirò ovunque finché sarai nei miei genitori
Ti aspettavi qualcosa di intelligente qui, vero? So che l'hai fatto! Fess up!

Il CSS

 .section padding: 10px; larghezza: 900px; margine: 0 auto; background-color: # f1f1f1; position: relative;  .section .content height: 800px; background-color: #ddd; margin-left: 250px; text-align: center; color: # 333; font-size: 16px;  .seection .menu position: absolute; a sinistra: 10px; larghezza: 240px; altezza: 100px; sfondo: # 06C; text-align: center; color: #fff; font-size: 14px; 

Il JavaScript

 $ ('# menu'). stickyfloat (duration: 400); $ ('# menu2'). stickyfloat (duration: 400);

Se leggi i file mentre leggi questo articolo, dovrebbe essere abbastanza auto-esplicativo, ma sei più che benvenuto a colpirmi con domande se qualche parte non è chiara.


Avvolgendo

E abbiamo finito. Abbiamo dato un'occhiata a un plugin incredibilmente utile, abbiamo analizzato il codice sorgente e alla fine abbiamo creato un mini progetto con esso.

Domande? Belle cose da dire? Critiche? Colpisci la sezione dei commenti e lasciami un commento. Grazie mille per la lettura!