Om de week houden we een ultragerichte kijk op een interessant en nuttig effect, plug-in, hack, bibliotheek of zelfs een handige technologie. We proberen dan de code te deconstrueren of er een leuk klein project mee te maken.
Vandaag gaan we een plug-in bekijken die een vrij netjes effect bewerkstelligt - het is vrij moeilijk om het in een zin uit te leggen, dus je kunt net zo goed op de knop Doorgaan klikken om te beginnen na de sprong.
Als webontwikkelaars hebben we toegang tot een duizelingwekkende hoeveelheid kant-en-klare code, of het nu een klein fragment is of een volledig ontwikkeld raamwerk. Tenzij je iets ongelooflijk speciaals doet, is de kans groot dat er al iets vooraf is voorbereid dat je kunt gebruiken. Jammer genoeg kwijnen veel van deze geweldige aanbiedingen in anonimiteit, speciaal voor de niet-hardcore menigte.
Deze serie probeert dit probleem op te lossen door het introduceren van een aantal echt goed geschreven, nuttige code - zij het een plug-in, een effect of een technologie voor de lezer. Verder, als het klein genoeg is, zullen we proberen de code te deconstrueren en begrijpen hoe het voodoo doet. Als het veel groter is, zullen we proberen om er een miniproject mee te maken om de touwen te leren en hopelijk te begrijpen hoe we het in de echte wereld kunnen gebruiken.
Hier is wat snelle info:
In veel gevallen moet u de inhoud laten zweven terwijl u bladert, maar alleen binnen zijn ouder.
Zwevende inhoud terwijl een gebruiker door de rest van de pagina scrolt, is kinderspel. JavaScript is niet nodig - u kunt het gewoon doen met oude CSS. Klap een positie: vast
verklaring erover en boom !, je hebt een container die op een specifieke locatie op de pagina is gerepareerd - het zweeft in de pagina om meer informeel te zijn.
Maar laten we eerlijk zijn, het werkt niet bij elke lay-out. Je zou een beetje vooruit kunnen plannen en het op de pagina kunnen plaatsen, zodat het nooit zou interfereren met belangrijke elementen, maar het zou noch volledig onfeilbaar noch herbruikbaar zijn elders zonder uitgebreide veranderingen.
In deze gevallen moet de inhoud zwevend zijn terwijl u bladert, maar alleen binnen zijn ouder.. Als je je afvraagt, ja, deze functionaliteit is een variant van degene die Andrew je liet zien in de tutorial van vorige week, en dat is hoe ik deze plug-in te weten kwam.
Zoals je zult vinden in webontwikkeling, net zoals multivariabele calculus, zijn er vaak een aantal oplossingen voor een bepaald probleem. Laten we naar een van die alternatieve oplossingen kijken.
De algemene logica of workflow van de plug is eigenlijk vrij eenvoudig. Ik zal het je laten zien. Houd in gedachten dat ik naar het element zal verwijzen dat moet worden bestuurd kleverig van nu af aan.
Maar voordat we beginnen, is hier een snelle mock-up om de hiërarchie te tonen:
De volledige logica van de plug-in kan worden afgezwakt tot:
Als je in de war bent, wees dat dan niet. Laten we bijvoorbeeld een aantal voorbeeldnummers bekijken:
Dus op basis van bovenstaande informatie kun je dat afleiden
In scenario één - de plakker moet op de juiste manier opnieuw worden geduwd. Waarom? De pagina is 10x gescrolld vanaf de top - 10 komt van de pagina zelf, terwijl de rest van de ouder van de sticky komt. De ouder is dus zichtbaar in het hoofdvenster.
In scenario twee - de plakker kan alleen worden gelaten. Van de 150 pixels komt 10 van de pagina, 100 van het bovenliggende element en de rest wordt overgenomen door de rest van het pagina-element. Dit houdt in dat de gebruiker voorbij de ouder is gescrold en dat we niets hoeven te doen.
Als je op dit moment nog steeds wazig bent, maak je geen zorgen. Ik zal een beetje meer uitleggen tijdens het wandelen door de bron.
De bron ontdaan van opmerkingen is slechts een smidgen van meer dan 30 regels lang. Zoals altijd zullen we de code doorlopen en uitleggen wat elke regel doet.
Hier is de bron, ter referentie.
$ .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, duration: 200, lockBottom: true, options); $ obj.css (position: 'absolute'); if (opts.lockBottom) var bottomPos = $ obj.parent (). height () - $ obj.height () + parentPaddingTop; if (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 ); ); ;
Tijd om te zien wat het eigenlijk doet. Ik ga ervan uit, je hebt een redelijk basiskenmerk van JavaScript.
$ .fn.stickyfloat = function (options, lockBottom) ;
Stap 1 - De generieke wrapper voor een jQuery-plug-in. Zoals je waarschijnlijk weet, opties
is een object dat verschillende opties bevat om het gedrag van de plug-in te configureren. lockBottom
, Interessant, geeft aan of de gewenste functionaliteit is ingeschakeld of niet. We laten het maar aan.
var $ obj = this;
Stap 2 - Houd een verwijzing naar het doorgegeven element bij. In deze context, deze
verwijst naar het DOM-element dat overeenkomt met de selector die je hebt doorgegeven. Bijvoorbeeld als je bent geslaagd #menu
, deze
wijst naar het element met die ID.
var parentPaddingTop = parseInt ($ obj.parent (). css ('padding-top'));
Stap 3 - Dit is alleen om het effect glad te strijken als het bovenliggende element een grote opvulling heeft. Als dit het geval is, bevat dit de opvulling in de berekening.
var startOffset = $ obj.parent (). offset (). top;
Stap 4 - We berekenen de positie van de ouder ten opzichte van het document met behulp van de compenseren
jQuery-methode. We werken via de DOM met behulp van de ouder
methode. Wij $ obj
omdat we het plakkerige al hebben gecached. Druk op de jQuery API-documentatie als u niet bekend bent met deze methoden.
In dit geval is de afstand vanaf de bovenkant voldoende, zodat we die waarde alleen krijgen.
var opts = $ .extend (startOffset: startOffset, offsetY: parentPaddingTop, duration: 200, lockBottom: true, options);
Stap 5 - Een vrij algemeen onderdeel van het ontwikkelproces voor jQuery-plug-ins. We voegen in essentie de doorgegeven opties samen met een aantal presets samen om een laatste reeks opties te krijgen die in de hele code wordt gebruikt. Houd er rekening mee dat de doorgegeven parameters altijd voorrang hebben op de standaardwaarden.
$ obj.css (position: 'absolute');
Stap 6 - Het betreffende effect wordt gecreëerd door het manipuleren van de elementen top
CSS-waarde, dus we gaan gewoon door en stellen de positie in op absoluut als deze nog niet zo is ingesteld.
if (opts.lockBottom) var bottomPos = $ obj.parent (). height () - $ obj.height () + parentPaddingTop; if (bottomPos < 0 ) bottomPos = 0;
Stap 7 - Zoals hierboven vermeld, de lockBottom
optie geeft aan of het effect in kwestie werkt of niet. Indien ingeschakeld, kunnen we beginnen met het berekenen. Wat we berekenen, is het afkappunt waarboven we het kleverige niet hoeven te verplaatsen.
Natuurlijk kun je gaan door gewoon de hoogte van de ouder te berekenen, maar het effect zal ongeraffineerd zijn. Je moet rekening houden met de hoogte van de plakker zelf langs eventuele paddings op de ouder zelf.
$ (venster) .scroll (function () // veel code)
Stap 8 - We haken onze code, binnen een anonieme functie, aan de ramen ' rol
evenement. Toegegeven, dit is niet de meest efficiënte manier om verder te gaan, maar we zullen het voorlopig negeren.
$ Obj.stop ();
Stap 9 - De eerste volgorde van zeggen is om alle lopende animaties op het plakkerige element te stoppen. De hou op
methode zorgt hier voor.
var pastStartOffset = $ (document) .scrollTop ()> opts.startOffset; var objFartherThanTopPos = $ obj.offset (). top> startOffset; var objBiggerThanWindow = $ obj.outerHeight () < $(window).height();
Stap 10 - Deze drie variabelen bevatten waarden die we een beetje later zullen gebruiken.
pastStartOffset
controleert of we voorbij de bovengrens van het bovenliggende element zijn gescrold. Vergeet niet dat we de compenseren
methode om de ruimte tussen het bovenliggende element en het document te achterhalen. We weten hoe ver je bent gescrold met behulp van de scrollTop
methode. Dit is de afstand tussen de bovenkant van het document en de bovenkant van de huidige viewport. objFartherThanTopPos
controleert of de sticky zich in de standaardpositie bevindt - op de bovenzijde van de bovenliggende. Als we voorbij de top
van de ouder, we willen niet dat het buiten zweeft.objBiggerThanWindow
controleert of de totale hoogte van de plakkerig is dan de grootte van het venster. Als dat het geval is, heeft het geen zin om het plakkerige element te manipuleren. if ((pastStartOffset || objFartherThanTopPos) && objBiggerThanWindow) // Meer code
Stap 11 - Dit is waar de plug-in berekent of we het kleverige element moeten manipuleren. Wat de bovenstaande regel doet:
We gaan alleen verder als beide van deze voorwaarden zijn voldaan.
var newpos = ($ (document) .scrollTop () -startOffset + opts.offsetY);
Stap 12 - Deze regel definieert een variabele, newpos
, die de positie specificeert waarnaar het sticky-element moet worden geanimeerd. Zoals je misschien hebt gemerkt, is de berekening redelijk eenvoudig als je de bovenstaande afbeelding in gedachten houdt. Ontdek de gescrolde afstand, voeg de bovenvulling van de bovenliggende laag toe en tenslotte de afstand tussen het document en de ouder af - het startpunt. Dit geeft je de afstand, in pixels, tussen de bovenkant van het bovenliggende element tot het punt binnenin, waar het plakkerige moet worden geplaatst.
if (newpos> bottomPos) newpos = bottomPos;
Stap 13 - Als we voorbij de ondergrens van het bovenliggende element hebben gescrolld, is het niet nodig om dingen verder te manipuleren. Vergrendel daar zijn positie.
if ($ (document) .scrollTop () < opts.startOffset ) newpos = parentPaddingTop;
Stap 14 - Als we boven de bovengrens van de ouder hebben gescrold, houd je deze daar vergrendeld zodat deze niet verder omhoog komt.
$ obj.animate (top: newpos, opts.duration);
Stap 15 - Helemaal klaar! We animeren eenvoudigweg het kleverige element dat de vereiste doorgeeft top
waarde samen met de duur van het effect met behulp van de bezielen
jQuery-methode.
Zoals je waarschijnlijk op dit punt al hebt afgeleid, is het gebruik als volgt:
$ ('# menu'). stickyfloat (duration: 500);>
In plaats van het voorbeeld mini-project uit te leggen, zoals de vorige keer, heb ik in plaats daarvan besloten om het alleen maar te bouwen en je de code te geven.
Hier zijn de relevante delen van de demo, de rest is boilerplate:
Kleverig menuIk wilde hier iets ongelooflijks, ongegeneerd geestigs schrijven. Ik faalde. :(Ja, ik volg je overal zolang je binnen mijn ouder bentJe verwachtte hier iets slims, is het niet? Ik weet dat je het deed! Fess up!
.sectie opvulling: 10px; width: 900px; marge: 0 auto; background-color: # f1f1f1; position: relative; .sectie .content height: 800px; background-color: #ddd; margin-left: 250px; text-align: center; color: # 333; font-size: 16px; .sectie .menu positie: absoluut; left: 10px; width: 240px; Hoogte: 100px; achtergrond: # 06C; text-align: center; color: # fff; font-size: 14px;
$ ('# menu'). stickyfloat (duration: 400); $ ('# menu2'). stickyfloat (duration: 400);
Als je de bestanden doorleest terwijl je dit artikel leest, zou het redelijk zelfverklarend moeten zijn, maar je bent meer dan welkom om me te slaan met vragen als een onderdeel onduidelijk is.
En we zijn klaar. We hebben een ongelooflijk nuttige plug-in bekeken, de broncode doorlopen en uiteindelijk klaar met het maken van een miniproject.
Vragen? Leuke dingen om te zeggen? Kritiek? Klik op het gedeelte Opmerkingen en laat een opmerking achter. Heel erg bedankt voor het lezen!