Als er een is slecht ding over jQuery, het is dat het instapniveau zo verbazingwekkend laag is dat het mensen aantrekt die geen greintje JavaScriptkennis hebben. Nu is dit aan de ene kant fantastisch. Echter, aan de andere kant, resulteert het ook in een beetje van, eerlijk gezegd, walgelijk slechte code (waarvan ik er zelf een heb geschreven!).
Maar dat is oke; angstaanjagend slechte code die je grootmoeder er zelfs van zou doen happen is een rite de passage. De sleutel is om over de heuvel te klimmen, en dat bespreken we in de tutorial van vandaag.
Het is belangrijk om te onthouden dat de meeste methoden het jQuery-object retourneren. Dit is uiterst nuttig en zorgt voor de ketenfunctionaliteit die we zo vaak gebruiken.
$ someDiv .attr ('class', 'someClass') .hide () .html ('nieuwe dingen');
Wetende dat het jQuery-object altijd wordt geretourneerd, kunnen we dit gebruiken om soms overtollige code te verwijderen. Neem bijvoorbeeld de volgende code in overweging:
var someDiv = $ ('# someDiv'); someDiv.hide ();
De reden waarom we de locatie van het
someDiv
element is om het aantal keren te beperken dat we de DOM voor dit element één keer moeten doorlopen.
De bovenstaande code is perfect in orde; u kunt echter net zo goed de twee lijnen samenvoegen tot één, terwijl hetzelfde resultaat wordt behaald.
var someDiv = $ ('# someDiv'). hide ();
Op deze manier verbergen we nog steeds de someDiv
element, maar de methode retourneert ook, zoals we hebben geleerd, het jQuery-object - waarnaar vervolgens wordt verwezen via de someDiv
veranderlijk.
Zolang uw selectors niet belachelijk slecht zijn, doet jQuery het fantastisch om deze zo goed mogelijk te optimaliseren, en u hoeft zich over het algemeen niet al te veel zorgen over hen te maken. Echter, met dat gezegd, zijn er een handvol verbeteringen die je kunt maken die de prestaties van je script iets zullen verbeteren.
Een dergelijke oplossing is om de vind()
methode, indien mogelijk. De sleutel verdwijnt van het forceren van jQuery om zijn Sizzle-engine te gebruiken, als dat niet nodig is. Zeker, er zullen momenten zijn waarop dit niet mogelijk is - en dat is oke; maar als je de extra overhead niet nodig hebt, ga er dan niet naar op zoek.
// Prima in moderne browsers, hoewel Sizzle begint met "running" $ ('# someDiv p.someClass'). Hide (); // Beter voor alle browsers en Sizzle nooit. . $ ( '# SomeDiv') vinden ( 'p.someClass') te verbergen ().;
De nieuwste moderne browsers hebben ondersteuning voor
QuerySelectorAll
, waarmee je CSS-achtige selectors kunt doorgeven, zonder dat je jQuery nodig hebt. jQuery zelf controleert ook voor deze functie.
Oudere browsers, namelijk IE6 / IE7, bieden begrijpelijkerwijs geen ondersteuning. Wat dit betekent is dat deze meer gecompliceerde selectors de volledige Sizzle-engine van jQuery activeren, die, hoewel briljant, met een beetje meer overhead komt.
Sissen is een briljante massa code die ik misschien nooit zal begrijpen. Echter, in een zin neemt het eerst je selector en verandert het in een "array" samengesteld uit elk onderdeel van je selector.
// Ruw idee hoe het werkt ['#someDiv,' p '];
Vervolgens begint het van rechts naar links om elk item te ontcijferen met reguliere expressies. Wat dit ook betekent, is dat het meest rechtse deel van uw selector zo specifiek mogelijk moet zijn, bijvoorbeeld een ID kaart
of tag naam.
Bottom line, indien mogelijk:
vind()
methode. Op deze manier kunnen we in plaats van Sizzle de native functies van de browser blijven gebruiken. Het is ook mogelijk om een context toe te voegen aan uw selectors, zoals:
$ ('. someElements', '#someContainer'). hide ();
Deze code dirigeert jQuery om een verzameling van alle elementen te wikkelen met een klasse van someElements
-- dat zijn kinderen van someContainer
-- binnen jQuery. Het gebruik van een context is een handige manier om de DOM-traversal te beperken, hoewel achter de schermen jQuery de vind
methode in plaats daarvan.
$ ('# someContainer') .find ('. someElements') .hide ();
// HANDLE: $ (expr, context) // (wat gelijk is aan: $ (context) .find (expr) else return jQuery (context) .find (selector);
$ (This)
Zonder van de verschillende DOM-eigenschappen en -functies op de hoogte te zijn, kan het eenvoudig zijn misbruik het jQuery-object onnodig. Bijvoorbeeld:
$ ('# someAnchor'). klik (function () // Bleh alert ($ (this) .attr ('id')););
Als onze enige behoefte aan het jQuery-object is om toegang te krijgen tot de ankertags ID kaart
attribuut, dit is verspilling. Het is beter om vast te houden aan "onbewerkt" JavaScript.
$ ('# someAnchor'). klik (functie () alert (this.id););
Let op: er zijn drie attributen die altijd toegankelijk moeten zijn, via jQuery: "src," "href," and "style." Deze attributen vereisen het gebruik van
getAttribute
in oudere versies van IE.
// jQuery-bron var rspecialurl = / href | src | style /; // ... var special = rspecialurl.test (name); // ... var attr =! JQuery.support.hrefNormalized && notxml && special? // Sommige attributen vereisen een speciale aanroep op IE elem.getAttribute (name, 2): elem.getAttribute (name);
Erger nog, is het herhaaldelijk ondervragen van de DOM en het maken van meerdere jQuery-objecten.
$ ( '# Elem') te verbergen ().; $ ( '# Elem') html ( 'bla.'); $ ( '# Elem') otherStuff (.);
Hopelijk weet u al hoe inefficiënt deze code is. Zo niet, dat is oke; we zijn allemaal aan het leren. Het antwoord is om ketens te implementeren of om de locatie van te cachen #elem
.
// Dit werkt beter $ ('# elem') .hide () .html ('bla') .otherStuff (); // Of dit, als u om een of andere reden wilt. var elem = $ ('# elem'); elem.hide (); elem.html (bla); elem.otherStuff ();
Klaar
Methode Luisteren naar wanneer het document klaar is om te worden gemanipuleerd, is lachwekkend eenvoudig met jQuery.
$ (document) .ready (function () // laten we opstaan in heeya);
Het is echter heel goed mogelijk dat je een andere, meer verwarrende inpakfunctie tegenkomt.
$ (function () // laten we opstaan in heeya);
Hoewel de laatste iets minder leesbaar is, zijn de twee bovenstaande fragmenten identiek. Geloof me niet? Controleer de jQuery-bron.
// HANDLE: $ (functie) // Sneltoets voor document gereed als (jQuery.isFunction (selector)) return rootjQuery.ready (selector);
rootjQuery
is gewoon een verwijzing naar de root jQuery (document)
. Wanneer u een selector doorgeeft aan de functie jQuery, bepaalt deze welk type selector u hebt doorgegeven: string, tag, id, functie, enzovoort. Als een functie is doorgegeven, roept jQuery de klaar()
methode en geef uw anonieme functie door aan de selector.
Als u code ontwikkelt voor distributie, is het altijd belangrijk om te compenseren voor een mogelijke naam die botst. Wat zou er gebeuren als een script dat na het jouwe werd geïmporteerd ook een $
functie? Slecht spul!
Het antwoord is om jQuery's te bellen geen conflict()
, of om uw code op te slaan in een zelfoproepende anonieme functie en vervolgens jQuery door te geven.
var j = jQuery.noConflict (); // Nu gebruiken we in plaats van $ j. . J ( '# someDiv') te verbergen (); // De regel hieronder verwijst naar de $ functie van een andere bibliotheek. $ ('someDiv'). style.display = 'none';
Wees voorzichtig met deze methode en probeer deze niet te gebruiken bij het verspreiden van uw code. Het zou de gebruiker van je script echt verwarren! :)
(functie ($) // In deze functie verwijst $ altijd naar jQuery) (jQuery);
De laatste parems onderaan roepen de functie automatisch aan - functie()()
. Wanneer we echter de functie aanroepen, geven we ook jQuery door, wat vervolgens wordt weergegeven door $
.
Klaar
Methode jQuery (document) .ready (functie ($) // $ verwijst naar jQuery); // $ is niet gedefinieerd of verwijst naar de functie van een andere bibliotheek.
Onthoud - jQuery is gewoon JavaScript. Ga er niet vanuit dat het de capaciteit heeft om te compenseren voor uw slechte codering. :)
Dit betekent dat, net zoals we dingen als JavaScript moeten optimaliseren voor
statements, hetzelfde geldt voor jQuery's elk
methode. En waarom zouden we niet? Het is gewoon een hulpmethode, die vervolgens een voor
verklaring achter de schermen.
// jQuery's elke methode bron elk: functie (object, callback, args) var name, i = 0, length = object.length, isObj = length === undefined || jQuery.isFunction (object); if (args) if (isObj) for (naam in object) if (callback.apply (object [naam], args) === false) break; else voor (; i < length; ) if ( callback.apply( object[ i++ ], args ) === false ) break; // A special, fast, case for the most common use of each else if ( isObj ) for ( name in object ) if ( callback.call( object[ name ], name, object[ name ] ) === false ) break; else for ( var value = object[0]; i < length && callback.call( value, i, value ) !== false; value = object[++i] ) return object;
someDivs.each (function () $ ('# anotherDiv') [0] .innerHTML + = $ (this) .text (););
anotherDiv
voor elke iteratie var someDivs = $ ('# container'). find ('. someDivs'), contents = []; someDivs.each (function () contents.push (this.innerHTML);); $ ('# anotherDiv'). html (contents.join ("));
Op deze manier, binnen de elk
(voor) methode, de enige taak die we uitvoeren is het toevoegen van een nieuwe sleutel aan een array ... in tegenstelling tot het bevragen van de DOM, het grijpen van de innerHTML
eigenschap van het element twee keer, enz.
Deze tip is meer op JavaScript gebaseerd in het algemeen, dan op jQuery-specifiek. Het punt is om te onthouden dat jQuery de slechte codering niet compenseert.
Terwijl we bezig zijn, is een andere optie voor dit soort situaties het gebruik van documentfragmenten.
var someUls = $ ('# container'). find ('. someUls'), frag = document.createDocumentFragment (), li; someUls.each (function () li = document.createElement ('li'); li.appendChild (document.createTextNode (this.innerHTML)); frag.appendChild (li);); $ ('# anotherUl') [0] .appendChild (frag);
De sleutel hier is dat er meerdere manieren zijn om eenvoudige taken als deze uit te voeren, en elk heeft zijn eigen prestatie-voordelen van browser tot browser. Hoe meer je vasthoudt aan jQuery en JavaScript leert, je kunt ook vinden dat je vaker naar de native eigenschappen en methoden van JavaScript verwijst. En zo ja, dat is fantastisch!
jQuery biedt een verbazingwekkend niveau van abstractie waar je van zou moeten profiteren, maar dit betekent niet dat je gedwongen wordt om zijn methoden te gebruiken. In het bovenstaande fragmentvoorbeeld gebruiken we bijvoorbeeld jQuery's elk
methode. Als u liever een voor
of terwijl
verklaring in plaats daarvan, dat is oke ook!
Houd er rekening mee dat het jQuery-team deze bibliotheek enorm heeft geoptimaliseerd. De debatten over jQuery's
elk()
tegen de inboorlingvoor
verklaring is dom en triviaal. Als u jQuery in uw project gebruikt, bespaar dan tijd en gebruik hun hulpmethoden. Daar zijn ze voor! :)
Als je nu net begint aan het graven in jQuery, kunnen de verschillende AJAX-methoden die het ons ter beschikking stelt een beetje ontmoedigend overkomen; hoewel ze dat niet nodig hebben. In feite zijn de meeste van hen gewoon hulpmethoden, die rechtstreeks naar verwijzen $ .ajax
.
Laten we het bijvoorbeeld eens bekijken getJSON
, waarmee we JSON kunnen ophalen.
$ .getJSON ('pad / naar / json', functie (resultaten) // callback // resultaten bevat het geretourneerde data-object);
Achter de schermen roept deze methode eerst op $ .get
.
getJSON: function (url, data, callback) return jQuery.get (url, data, callback, "json");
$ .get
compileert dan de doorgegeven gegevens en roept opnieuw de "meester" (van soorten) $ .ajax
methode.
get: function (url, data, callback, type) // verschuif argumenten als data argument was weggelaten if (jQuery.isFunction (data)) type = type || Bel terug; callback = data; data = null; retourneer jQuery.ajax (type: "GET", url: url, data: data, succes: callback, dataType: type);
Tenslotte, $ .ajax
verricht een enorme hoeveelheid werk om ons in staat te stellen om met succes asynchrone verzoeken in alle browsers te maken!
Wat dit betekent is dat je net zo goed de
$ .ajax
methode direct en exclusief voor al uw AJAX-verzoeken. De andere methoden zijn eenvoudig hulpmethoden die dit toch doen. Dus, als je wilt, knip de middelste man uit. Het is hoe dan ook geen belangrijk probleem.
$ .getJSON ('pad / naar / json', functie (resultaten) // callback // resultaten bevat het geretourneerde data-object);
$ .ajax (type: 'GET', url: 'path / to / json', data: yourData, dataType: 'json', success: function (results) console.log ('success');) );
U hebt dus een beetje JavaScript geleerd en hebt geleerd dat u bijvoorbeeld op ankertags rechtstreeks toegang kunt krijgen tot kenmerkwaarden:
var anchor = document.getElementById ('someAnchor'); //anchor.id // anchor.href // anchor.title // .etc
Het enige probleem is dat dit niet lijkt te werken wanneer je naar de DOM-elementen verwijst met jQuery, toch? Nou natuurlijk niet.
// Fails var id = $ ('# someAnchor'). Id;
Dus, zou u toegang moeten hebben tot de href
attribuut (of een andere native eigenschap of methode voor die kwestie), je hebt een handvol opties.
// OPTIE 1 - Gebruik jQuery var id = $ ('# someAnchor'). Attr ('id'); // OPTIE 2 - Toegang krijgen tot het DOM-element var id = $ ('# someAnchor') [0] .id; // OPTIE 3 - Gebruik de methode get van jQuery var id = $ ('# someAnchor'). Get (0) .id; // OPTIE 3b - Geef geen index om anchorsArray = $ ('. SomeAnchors'). Get (); var thirdId = anchorsArray [2] .id;
De
krijgen
methode is bijzonder nuttig, omdat het uw jQuery-verzameling in een array kan vertalen.
Zeker, voor de overgrote meerderheid van onze projecten kunnen we dat niet enkel en alleen vertrouw op JavaScript voor zaken als validatie of AJAX-verzoeken. Wat gebeurt er als JavaScript is uitgeschakeld? Om deze reden is een veel gebruikte techniek om te detecteren of een AJAX-verzoek is gedaan met uw taal op de server naar keuze.
jQuery maakt dit belachelijk eenvoudig, door een header in te stellen vanuit de $ .ajax
methode.
// Stel de header zo in dat het aangeroepen script weet dat het een XMLHttpRequest is // Stuur alleen de header als het geen externe XHR is als (! Remote) xhr.setRequestHeader ("X-Requested-With", "XMLHttpRequest");
Met deze header-set kunnen we nu PHP (of een andere taal) gebruiken om te controleren op deze header en dienovereenkomstig te handelen. Hiervoor controleren we de waarde van $ _SERVER [ 'HTTP_X_REQUESTED_WITH']
.
function isXhr () return $ _SERVER ['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
Ooit afgevraagd waarom / hoe je kunt gebruiken jQuery
en $
uitwisselbaar? Om uw antwoord te vinden, bekijkt u de jQuery-bron en scrolt u helemaal naar beneden. Daar zie je:
window.jQuery = venster. $ = jQuery;
Het volledige jQuery-script is natuurlijk verpakt in een zelf-uitvoerende functie, waardoor het script het aantal globale variabelen zoveel mogelijk kan beperken. Wat dit echter ook betekent, is dat het jQuery-object niet beschikbaar is buiten de anonieme functie voor omloop.
Om dit te verhelpen, wordt jQuery blootgesteld aan het globale venster
object en, in dit proces, een alias - $
- is ook gemaakt.
HTML5 Boilerplate biedt een handige one-liner die een lokale kopie van jQuery laadt als om een vreemde reden de gekozen CDN niet beschikbaar is.
Om de bovenstaande code "uit te spreken": als window.jQuery niet gedefinieerd is, moet er een probleem zijn opgetreden bij het downloaden van het script van de CDN. Ga in dat geval naar de rechterkant van de &&
operator en voeg een script in dat linkt naar een lokale versie van jQuery.
Premium-leden: download deze video (moet ingelogd zijn)
Abonneer u op onze YouTube-pagina om alle videozelfstudies te bekijken!
Notitie:
jQuery.expr [ '']
is gewoon een alias voorjQuery.expr.filters
.
Vanaf jQuery 1.4 kunnen we nu slechts één enkele functie doorgeven aan de zweven
methode. Vroeger waren beide in en uit methoden waren vereist.
$ ('# someElement'). hover (function () // mouseover, function () // mouseout);
$ ('# someElement'). hover (function () // de toggle () -methode kan hier worden gebruikt, indien van toepassing);
Merk op dat dit geen oude versus nieuwe deal is. Vaak moet je nog steeds twee functies doorgeven zweven
, en dat is perfect acceptabel. Als u echter maar een element (of iets dergelijks) hoeft in te schakelen, zal het passeren van een enkele anonieme functie een handvol tekens of zo opslaan!
Vanaf jQuery 1.4 kunnen we een object nu als de tweede parameter van de jQuery-functie doorgeven. Dit is handig als we nieuwe elementen in de DOM moeten invoegen. Bijvoorbeeld:
$ ('') .attr (id: 'someId', className: 'someClass', href: 'somePath.html');
$ ('', id: 'someId', className: 'someClass', href: 'somePath.html');
Dit bespaart niet alleen een paar tekens, maar zorgt ook voor schonere code. Naast elementattributen kunnen we zelfs jQuery-specifieke kenmerken en gebeurtenissen doorgeven, zoals Klik
of tekst
.