Se ce n'è uno male per quanto riguarda jQuery, è che il livello di ingresso è così incredibilmente basso, che tende ad attrarre coloro che non hanno un'oncia di conoscenza di JavaScript. Ora, da un lato, questo è fantastico. Tuttavia, il rovescio della medaglia, si traduce anche in un'infarinatura di codice, francamente, disgustosamente cattivo (alcuni dei quali mi sono scritto!).
Ma è ok; Un codice spaventosamente scadente che potrebbe persino far sussultare tua nonna è un rito di passaggio. La chiave è scavalcare la collina, ed è quello che discuteremo nel tutorial di oggi.
È importante ricordare che la maggior parte dei metodi restituirà l'oggetto jQuery. Ciò è estremamente utile e consente la funzionalità di concatenazione che usiamo così spesso.
$ someDiv .attr ('class', 'someClass') .hide () .html ('new stuff');
Sapendo che l'oggetto jQuery viene sempre restituito, possiamo usarlo per rimuovere il codice superfluo, a volte. Ad esempio, considera il seguente codice:
var someDiv = $ ('# someDiv'); someDiv.hide ();
Il motivo per cui "memorizziamo" la posizione del file
someDiv
l'elemento è di limitare il numero di volte in cui dobbiamo attraversare il DOM per questo elemento in una sola volta.
Il codice sopra è perfettamente a posto; tuttavia, potresti facilmente combinare le due linee in una sola, ottenendo lo stesso risultato.
var someDiv = $ ('# someDiv'). hide ();
In questo modo, nascondiamo ancora il someDiv
elemento, ma anche il metodo, come abbiamo appreso, restituisce l'oggetto jQuery, che viene quindi referenziato tramite someDiv
variabile.
Finché i tuoi selezionatori non sono ridicolmente poveri, jQuery fa un lavoro fantastico per ottimizzarli al meglio, e generalmente non devi preoccuparti troppo di loro. Tuttavia, con ciò detto, ci sono una serie di miglioramenti che è possibile apportare che miglioreranno leggermente le prestazioni del tuo script.
Una tale soluzione è usare il trova()
metodo, quando possibile. La chiave è lontana dal forzare jQuery a usare il suo motore Sizzle, se non è necessario. Certamente, ci saranno momenti in cui questo non è possibile - e va bene così; ma, se non si richiede l'overhead in eccesso, non andare a cercarlo.
// Bene nei browser moderni, anche se Sizzle inizia "running" $ ('# someDiv p.someClass'). Hide (); // Meglio per tutti i browser e Sizzle non si avvia mai. . $ ( '# SomeDiv') trovare ( 'p.someClass') hide ().;
Gli ultimi browser moderni hanno il supporto per
querySelectorAll
, che ti permette di passare selettori simili a CSS, senza la necessità di jQuery. jQuery controlla anche questa funzione.
Tuttavia, i browser più vecchi, ovvero IE6 / IE7, non forniscono comprensibilmente supporto. Ciò significa che questi selettori più complicati attivano il motore Sizzle completo di jQuery, il quale, sebbene brillante, presenta un po 'più di overhead.
Sizzle è una massa di codice geniale che potrei non capire mai. Tuttavia, in una frase, prima prende il tuo selettore e lo trasforma in un "array" composto da ciascun componente del tuo selettore.
// Rough idea di come funziona ['#someDiv,' p '];
Quindi, da destra a sinistra, inizia a decifrare ogni oggetto con espressioni regolari. Ciò significa anche che la parte più corretta del tuo selettore dovrebbe essere il più specifica possibile, ad esempio, a id
o nome del tag.
In conclusione, quando possibile:
trova()
metodo. In questo modo, anziché utilizzare Sizzle, possiamo continuare a utilizzare le funzioni native del browser. È anche possibile aggiungere un contesto ai selettori, come ad esempio:
$ ('. someElements', '#someContainer'). hide ();
Questo codice indirizza jQuery a racchiudere una raccolta di tutti gli elementi con una classe di someElements
-- che sono figli di someContainer
-- all'interno di jQuery. L'uso di un contesto è un modo utile per limitare l'attraversamento del DOM, tuttavia, dietro le quinte, jQuery usa il trova
metodo invece.
$ ('# someContainer') .find ('. someElements') .hide ();
// HANDLE: $ (expr, context) // (che è solo equivalente a: $ (context) .find (expr) else return jQuery (context) .find (selector);
$ (This)
Senza conoscere le varie proprietà e funzioni del DOM, può essere facile abuso l'oggetto jQuery inutilmente. Per esempio:
$ ('# someAnchor'). click (function () // Bleh alert ($ (this) .attr ('id')););
Se la nostra unica necessità dell'oggetto jQuery è di accedere ai tag di ancoraggio id
attributo, questo è uno spreco. Meglio restare con JavaScript "raw".
$ ('# someAnchor'). click (function () alert (this.id););
Tieni presente che ci sono tre attributi a cui è sempre necessario accedere, tramite jQuery: "src", "href" e "stile". Questi attributi richiedono l'uso di
getAttribute
nelle versioni precedenti di IE.
// jQuery Source var rspecialurl = / href | src | style /; // ... var special = rspecialurl.test (name); // ... var attr =! JQuery.support.hrefNormalized && notxml && special? // Alcuni attributi richiedono una chiamata speciale su IE elem.getAttribute (nome, 2): elem.getAttribute (nome);
Ancora peggio è il processo di interrogare ripetutamente il DOM e creare più oggetti jQuery.
$ ( '# Elem') nascondere ().; $ ( '# Elem') html ( 'bla.'); $ ( '# Elem') otherstuff ().;
Spero che tu sappia già quanto sia inefficiente questo codice. In caso contrario, va bene; stiamo tutti imparando. La risposta è implementare il concatenamento o "memorizzare" la posizione di #elem
.
// Funziona meglio $ ('# elem') .hide () .html ('bla') .otherStuff (); // O questo, se preferisci per qualche motivo. var elem = $ ('# elem'); elem.hide (); elem.html ( 'bla'); elem.otherStuff ();
Pronto
Metodo Ascoltare quando il documento è pronto per essere manipolato è ridicolmente semplice con jQuery.
$ (document) .ready (function () // alziamoci in heeya);
Tuttavia, è molto probabile che tu abbia trovato una funzione di wrapping diversa e più confusa.
$ (function () // alziamoci in heeya);
Sebbene quest'ultimo sia in qualche modo meno leggibile, i due frammenti sopra sono identici. Non mi credi? Basta controllare la fonte jQuery.
// MANIGLIA: $ (funzione) // Collegamento per documento pronto se (jQuery.isFunction (selettore)) return rootjQuery.ready (selector);
rootjQuery
è semplicemente un riferimento alla radice jQuery (document)
. Quando si passa un selettore alla funzione jQuery, verrà determinato il tipo di selettore passato: stringa, tag, id, funzione, ecc. Se è stata passata una funzione, jQuery chiamerà il suo pronto()
metodo e passare la funzione anonima come selettore.
Se si sviluppa codice per la distribuzione, è sempre importante compensare eventuali conflitti di nomi. Cosa succederebbe se qualche script, importato dopo il tuo, avesse anche un $
funzione? Brutta roba!
La risposta è chiamare uno jQuery noConflict ()
, o per memorizzare il codice all'interno di una funzione anonima autoinvitante, quindi passare jQuery su di esso.
var j = jQuery.noConflict (); // Ora, invece di $, usiamo j. . J ( '# someDiv') nascondere (); // La riga seguente farà riferimento alla funzione $ di un'altra libreria. $ ('someDiv'). style.display = 'none';
Fai attenzione con questo metodo e cerca di non usarlo quando distribuisci il tuo codice. Confonderebbe davvero l'utente del tuo script! :)
(function ($) // All'interno di questa funzione, $ farà sempre riferimento a jQuery) (jQuery);
Gli ultimi paren in fondo chiamano automaticamente la funzione - funzione()()
. Tuttavia, quando chiamiamo la funzione, passiamo anche a jQuery, che viene quindi rappresentato da $
.
Pronto
Metodo jQuery (document) .ready (function ($) // $ si riferisce a jQuery); // $ non è definito o fa riferimento ad altre funzioni della libreria.
Ricorda: jQuery è solo JavaScript. Non dare per scontato che abbia la capacità di compensare la tua cattiva codifica. :)
Ciò significa che, proprio come dobbiamo ottimizzare cose come JavaScript per
dichiarazioni, lo stesso vale per jQuery ogni
metodo. E perché non dovremmo? È solo un metodo di supporto, che quindi crea un per
affermazione dietro le quinte.
// jQuery ogni fonte di metodo ciascuna: function (oggetto, callback, args) var name, i = 0, length = object.length, isObj = length === undefined || jQuery.isFunction (oggetto); if (args) if (isObj) for (nome nell'oggetto) if (callback.apply (oggetto [nome], args) === false) break; else for (; 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
per ogni iterazione var someDivs = $ ('# container'). find ('. someDivs'), contents = []; someDivs.each (function () contents.push (this.innerHTML);); $ ('# anotherDiv'). html (contents.join ("));
In questo modo, all'interno del ogni
(per) metodo, l'unica attività che stiamo eseguendo è l'aggiunta di una nuova chiave a un array ... al contrario di interrogare il DOM, afferrando il innerHTML
proprietà dell'elemento due volte, ecc.
Questo suggerimento è più basato su JavaScript in generale, piuttosto che su jQuery. Il punto è ricordare che jQuery non compensa la scarsa codifica.
Mentre ci siamo, un'altra opzione per questo tipo di situazioni è l'uso di frammenti di documenti.
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);
La chiave qui è che ci sono diversi modi per svolgere compiti semplici come questo, e ognuno ha i propri vantaggi in termini di prestazioni dal browser al browser. Quanto più ti infili con jQuery e impari JavaScript, potresti anche scoprire che fai riferimento più spesso alle proprietà e ai metodi nativi di JavaScript. E, se è così, è fantastico!
jQuery fornisce uno straordinario livello di astrazione da cui trarre vantaggio, ma questo non significa che sei costretto a usare i suoi metodi. Ad esempio, nell'esempio di frammenti sopra, utilizziamo jQuery ogni
metodo. Se preferisci usare a per
o mentre
la dichiarazione invece, va bene anche così!
Detto questo, tieni presente che il team di jQuery ha ottimizzato notevolmente questa libreria. I dibattiti su jQuery
ogni()
contro il nativoper
le affermazioni sono sciocche e banali. Se stai usando jQuery nel tuo progetto, risparmia tempo e usa i loro metodi di supporto. Ecco a cosa servono! :)
Se stai appena iniziando a scavare in jQuery, i vari metodi AJAX che ci mette a disposizione potrebbero sembrare scoraggianti; sebbene non ne abbiano bisogno In realtà, molti di questi sono semplicemente metodi di supporto, che vengono indirizzati direttamente a $ .ajax
.
Ad esempio, rivediamo getJSON
, che ci permette di recuperare JSON.
$ .getJSON ('percorso / a / json', funzione (risultati) // callback // risultati contiene l'oggetto dati restituito);
Dietro le quinte, questo metodo prima chiama $ .get
.
getJSON: function (url, data, callback) return jQuery.get (url, data, callback, "json");
$ .get
quindi compila i dati passati e, ancora, chiama il "master" (di sorta) $ .ajax
metodo.
get: function (url, data, callback, type) // sposta gli argomenti se l'argomento data è stato omesso if (jQuery.isFunction (data)) type = type || richiama; callback = dati; data = null; return jQuery.ajax (type: "GET", url: url, data: data, success: callback, dataType: tipo);
Finalmente, $ .ajax
svolge un enorme lavoro per permetterci di fare richieste asincrone con successo su tutti i browser!
Cosa significa è che puoi anche usare il
$ .ajax
metodo direttamente ed esclusivamente per tutte le tue richieste AJAX. Gli altri metodi sono semplicemente metodi di supporto che finiscono per farlo comunque. Quindi, se vuoi, ritaglia l'uomo di mezzo. Non è un problema significativo in entrambi i casi.
$ .getJSON ('percorso / a / json', funzione (risultati) // callback // risultati contiene l'oggetto dati restituito);
$ .ajax (tipo: 'GET', url: 'percorso / a / json', dati: yourData, dataType: 'json', success: function (results) console.log ('success');) );
Quindi hai imparato un po 'di JavaScript e hai imparato che, ad esempio, sui tag di ancoraggio, puoi accedere direttamente ai valori degli attributi:
var anchor = document.getElementById ('someAnchor'); //anchor.id // anchor.href // anchor.title // .etc
L'unico problema è che questo non sembra funzionare quando fai riferimento agli elementi DOM con jQuery, giusto? Beh, certo che no.
// Fails var id = $ ('# someAnchor'). Id;
Quindi, dovresti aver bisogno di accedere a href
attributo (o qualsiasi altra proprietà o metodo nativo per quella materia), hai una manciata di opzioni.
// OPZIONE 1 - Usa jquery var id = $ ('# someAnchor'). Attr ('id'); // OPZIONE 2 - Accesso all'elemento DOM var id = $ ('# someAnchor') [0] .id; // OPZIONE 3 - Usa il metodo get di jQuery var id = $ ('# someAnchor'). Get (0) .id; // OPZIONE 3b - Non passare un indice per ottenere anchorsArray = $ ('. SomeAnchors'). Get (); var thirdId = anchorsArray [2] .id;
Il
ottenere
il metodo è particolarmente utile, in quanto può tradurre la tua collezione jQuery in una matrice.
Certamente, per la stragrande maggioranza dei nostri progetti, non possiamo solo fare affidamento su JavaScript per cose come la convalida o le richieste AJAX. Cosa succede quando JavaScript è disattivato? Proprio per questo motivo, una tecnica comune è quella di rilevare se è stata fatta una richiesta AJAX con il linguaggio di scelta del server.
jQuery rende questo ridicolmente semplice, impostando un'intestazione all'interno di $ .ajax
metodo.
// Imposta l'intestazione in modo che lo script chiamato sappia che è un XMLHttpRequest // Invia l'intestazione solo se non è un XHR remoto se (! Remote) xhr.setRequestHeader ("X-Requested-With", "XMLHttpRequest");
Con questo set di intestazione, ora possiamo usare PHP (o qualsiasi altra lingua) per verificare questa intestazione e procedere di conseguenza. Per questo, controlliamo il valore di $ _SERVER [ 'HTTP_X_REQUESTED_WITH']
.
function isXhr () return $ _SERVER ['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest';
Vi siete mai chiesti perché / come potete usare jQuery
e $
intercambiabile? Per trovare la risposta, visualizzare la sorgente jQuery e scorrere fino in fondo. Lì, vedrai:
window.jQuery = window. $ = jQuery;
L'intero script jQuery è, ovviamente, racchiuso in una funzione autoesecutiva, che consente allo script di limitare il più possibile il numero di variabili globali. Ciò significa anche, tuttavia, che l'oggetto jQuery non è disponibile al di fuori della funzione di wrapping anonimo.
Per risolvere questo problema, jQuery è esposto al globale finestra
oggetto e, nel processo, un alias - $
- è anche creato.
HTML5 Boilerplate offre un one-liner elegante che caricherà una copia locale di jQuery se, per qualche strana ragione, il tuo CDN scelto è giù.
Per "esprimere" il codice sopra: se window.jQuery è indefinito, deve essersi verificato un problema durante il download dello script dal CDN. In tal caso, procedere al lato destro del &&
operatore e inserire uno script che colleghi a una versione locale di jQuery.
Membri Premium: Scarica questo video (deve essere registrato)
Iscriviti alla nostra pagina YouTube per guardare tutti i tutorial video!
Nota:
jQuery.expr [ ':']
è semplicemente un alias perjQuery.expr.filters
.
A partire da jQuery 1.4, ora possiamo passare solo una singola funzione al librarsi
metodo. Prima, entrambi i nel e su i metodi erano richiesti.
$ ('# someElement'). hover (function () // mouseover, function () // mouseout);
$ ('# someElement'). hover (function () // il metodo toggle () può essere usato qui, se applicabile);
Si noti che questo non è un vecchio contro un nuovo accordo. Molte volte, dovrai ancora passare due funzioni librarsi
, e questo è perfettamente accettabile. Tuttavia, se hai solo bisogno di alternare qualche elemento (o qualcosa del genere), passare una singola funzione anonima salverà una manciata di caratteri o così!
A partire da jQuery 1.4, ora possiamo passare un oggetto come secondo parametro della funzione jQuery. Questo è utile quando abbiamo bisogno di inserire nuovi elementi nel DOM. Per esempio:
$ ('') .attr (id: 'someId', className: 'someClass', href: 'somePath.html');
$ ('', id: 'someId', className: 'someClass', href: 'somePath.html');
Non solo questo salva alcuni caratteri, ma rende anche il codice più pulito. Oltre agli attributi degli elementi, possiamo anche passare attributi ed eventi specifici di jQuery, come clic
o testo
.