Fie că ne place sau nu, tot mai mulți dezvoltatori sunt introduși în lumea JavaScript prin intermediul jQuery. În multe privințe, acești nou-veniți sunt cei norocoși. Ei au acces la o mulțime de noi API-uri JavaScript, ceea ce face considerabil mai ușor procesul de traversal DOM (ceva ce mulți oameni depind de jQuery pentru). Din păcate, ei nu știu despre aceste API-uri!
În acest articol, vom lua o varietate de sarcini jQuery comune și le vom transforma atât în JavaScript modern, cât și în vechime.
Modern vs. Legacy - Pentru fiecare articol din lista de mai jos, veți găsi modul modern, "cool copii" pentru a îndeplini sarcina și moștenirea, "face browserele vechi fericite". Alegerea pe care o alegeți pentru propriile proiecte va depinde în mare măsură de vizitatorii dvs..
Rețineți că unele dintre ele moştenire exemplele din acest articol vor face uz de un simplu browser încrucișat, addEvent
funcţie. Această funcție va asigura pur și simplu că atât modelul de eveniment recomandat de W3C, addEventListener
, și moștenirea lui Internet Explorer attachEvent
sunt normalizate.
Deci, când mă refer addEvent (els, eveniment, handler)
în fragmentele de coduri vechi de mai jos, se face referire la următoarea funcție.
var addEvent = (funcția () var filter = funcția (el, type, fn) pentru (var i = 0, len = el.length; i < len; i++ ) addEvent(el[i], type, fn); ; if ( document.addEventListener ) return function (el, type, fn) if ( el && el.nodeName || el === window ) el.addEventListener(type, fn, false); else if (el && el.length) filter(el, type, fn); ; return function (el, type, fn) if ( el && el.nodeName || el === window ) el.attachEvent('on' + type, function () return fn.call(el, window.event); ); else if ( el && el.length ) filter(el, type, fn); ; )(); // usage addEvent( document.getElementsByTagName('a'), 'click', fn);
$ ( '# Container');
Acest apel pentru funcții va interoga DOM pentru elementul cu un id
de recipient
, și să creeze un nou jQuery
obiect.
var container = document.querySelector ('container');
querySelector
face parte din API-ul Selectors, care ne oferă posibilitatea de a interoga DOM utilizând selectorii CSS pe care deja îi cunoaștem.
Această metodă particulară va returna primul element care se potrivește cu selectorul trecut.
var container = document.getElementById ('container');
Acordați o atenție deosebită modului în care faceți referire la element. Atunci când se utilizează getElementById
, treci singura valoare, în timp ce, cu querySelector
, un selector CSS este de așteptat.
. $ ( '# Container') găsește ( 'li');
De data aceasta, nu vânăm la un singur element; în schimb, capturam orice număr de elemente din listă din care sunt descendenți #container
.
var lis = Document.querySelectorAll ('# container li');
querySelectorAll
va reveni toate elemente care se potrivesc cu selectorul CSS specificat.
În timp ce aproape toate browserele relevante acceptă selectorul API, selectorii CSS specifici pe care îi transmiteți sunt încă limitați la capacitatea browserului. Traducerea: Internet Explorer 8 va suporta numai selectorii CSS 2.1.
var lis = document.getElementById ('container'); getElementsByTagName ('li');
$ ('a') pe ('faceți clic', fn);
În acest exemplu, atașăm a clic
ascultător de evenimente pentru toate etichetele de ancorare de pe pagină.
[]. forEach.call (document.querySelectorAll ('a'), funcția (el) el.addEventListener ('click', funcția () // anchor a fost apăsată, false););
Fragmentul de mai sus pare înfricoșător, dar nu este prea rău. pentru că querySelectorAll
returnează un static NodeList
mai degrabă decât unul mulțime
, nu putem accesa direct metode, cum ar fi pentru fiecare
. Acest lucru este remediat prin chemare pentru fiecare
pe mulțime
obiect, și trecerea rezultatelor querySelectorAll
la fel de acest
.
var anchors = document.getElementsbyTagName ('a'); addEvent (ancore, "clic", fn);
$ ("ul") pe ("faceți clic pe", "a", fn);
Ahh - acest exemplu este ușor diferit. De această dată, fragmentul jQuery folosește delegarea evenimentelor. clic
ascultătorul este aplicat tuturor listelor neordonate, cu toate acestea, funcția de apel invers se va declanșa numai dacă țintă (ceea ce utilizatorul a făcut clic în mod special) este o etichetă de ancorare.
document.addEventListener ("clic", funcția (e) if (e.target.matchesSelector ('ul a')) // continuă, falsă);
Din punct de vedere tehnic, această metodă JavaScript de la vanilla nu este aceeași cu exemplul jQuery. În schimb, acesta atașează direct ascultătorul evenimentului document
. Apoi utilizează noul matchesSelector
pentru a determina dacă ţintă
- nodul pe care sa făcut clic - se potrivește cu selectorul furnizat. În acest fel, atașăm un singur ascultător de evenimente, mai degrabă decât mulți.
Rețineți că, la momentul acestei scrieri, toate browserele se implementează matchesSelector
prin propriile lor prefixe: mozMatchesSelector
, webkitMatchesSelector
, etc. Pentru a normaliza metoda, s-ar putea scrie:
var meciuri; (funcția (doc) matches = doc.matchesSelector || doc.webkitMatchesSelector || doc.mozMatchesSelector || doc.oMatchesSelector || doc.msMatchesSelector;) (document.documentElement); document.addEventListener ("clic", funcția (e) if (match.call (e.target, 'ul a')) // continuă, false);
Cu această tehnică, în Webkit, meciurile se vor referi la
webkitMatchesSelector
, și, în Mozilla,mozMatchesSelector
.
var uls = document.getElementsByTagName ('ul'); addEvent (uls, 'click', functie () var target = e.target || e.srcElement; daca (target && target.nodeName === 'A') // continua);
Ca rezervă, determinăm dacă nodeName
proprietatea (numele elementului țintă) este egală cu interogarea dorită. Acordați o atenție deosebită faptului că versiunile mai vechi ale Internet Explorer joacă câteodată prin propriile reguli - cum ar fi copilul care mănâncă joacă-doh în timpul prânzului. Nu veți avea acces ţintă
direct de la eveniment
obiect. În schimb, veți dori să căutați event.srcElement
.
$ ( '# Caseta') addClass ( 'folie').;
jQuery oferă un API util pentru modificarea numelor de clasă pe un set de elemente.
document.querySelector ( '# caseta') classList.add ( 'folie').;
Această nouă tehnică folosește noua tehnologie classList
API la adăuga
, elimina
, și comutare
nume de clasă.
var container = document.querySelector ('caseta #'); container.classList.add ( 'folie'); container.classList.remove ( 'folie'); container.classList.toggle ( 'folie');
var box = document.getElementById ('box'), hasClass = functie (el, cl) var regex = noua RegExp ('(?: \\ s | ^)' + cl + ' ) "); retur! el.className.match (regex); , addClass = funcția (el, cl) el.className + = "+ cl;, removeClass = funcția (el, cl) var regex = new RegExp + '(?: \\ s | $)'); el.className = el.className.replace (regex, "); , toggleClass = funcția (el, cl) hasClass (el, cl)? ștergeClass (el, cl): addClass (el, cl); ; addClass (caseta, "drago"); removeClass (caseta, "drago"); toggleClass (caseta, "drago"); // dacă elementul nu are o clasă de "drago", adăugați unul.
Tehnica de rezervă necesită doar o treabă mai multă muncă, ay?
. $ ( '# Lista') următoare ();
lui jQuery Următor →
metoda va returna elementul care urmează imediat elementul curent din setul înfășurat.
var următoarea = document.querySelector ('# list') nextElementSibling; // IE9
nextElementSibling
se va referi în mod specific la următorul element nod, mai degrabă decât orice nod (text, comentariu, element). Din păcate, Internet Explorer 8 și versiunile anterioare nu o acceptă.
var list = document.getElementById ('lista'), next = list.nextSibling; // vrem ca nodul urmator al elementului ... nu text. în timp ce (next.nodeType> 1) next = next.nextSibling;
Există câteva moduri de a scrie acest lucru. În acest exemplu, detectăm nodeType
al nodului care urmează elementului specificat. Ar putea fi text, element sau chiar un comentariu. Întrucât avem nevoie în mod special de următorul element, dorim a nodeType
de 1
. Dacă next.nodeType
returnează un număr mai mare decât 1
, ar trebui să o ignorăm și să continuăm, deoarece este probabil un nod de text.
$ (“') .AppendTo (' organism ");
Pe lângă interogarea DOM, jQuery oferă și posibilitatea de a crea și injecta elemente.
var div = document.createElement ("div"); div.id = 'caseta'; document.body.appendChild (div);
Nu este nimic modern despre acest exemplu; este modul în care am realizat procesul de creare și injectare de elemente în DOM pentru o perioadă lungă de timp.
Probabil că va trebui să adăugați conținut la element, caz în care puteți fie să utilizați innerHTML
, sau createTextNode
.
div.appendChild (document.createTextNode ('wacka wacka')); // sau div.innerHTML = 'wacka wacka';
$ (Document) .ready (fn)
lui jQuery document.ready
metoda este incredibil de convenabilă. Aceasta ne permite să începem să executăm codul cât mai curând posibil după încărcarea DOM.
document.addEventListener ('DOMContentLoaded', funcția () // distracție);
Standardizat ca parte a HTML5, DOMContentLoaded
evenimentul se va declanșa imediat după ce documentul a fost finalizat.
// http://dustindiaz.com/smallest-domready-ever funcționează gata (cb) /in/.test(document.readyState) // in = loadINg? setTimeout ('gata (' + cb + ')', 9): cb (); gata (funcția () // apuca ceva de la DOM);
Soluția de rezervă, la fiecare nouă milisecunde, va detecta valoarea document.readyState
. Dacă se returnează "încărcarea", documentul nu a fost încă analizat complet (/in/.test ()
. Odată ce a avut, totuși, document.readyState
va fi egală cu "completă", moment în care funcția de apel invers a utilizatorului este executată.
css ("culoare", "roșu");
Dacă este posibil, adăugați întotdeauna a clasă
la un element, când trebuie să oferiți un stil special. Cu toate acestea, uneori, stilul va fi determinat dinamic, caz în care trebuie introdus ca atribut.
[]. forEach.call (document.querySelectorAll ("caseta"), funcția (el) el.style.color = 'roșu'; // sau adăugați o clasă);
Încă o dată, folosim [] .ForEach.call ()
tehnica de a filtra prin toate elementele cu o clasa de cutie
, și le face roșii, prin stil
obiect.
var box = document.getElementsByClassName ("caseta"), // consultați exemplul # 10 de mai jos pentru o soluție încrucișată în browser i = box.length; în timp ce (i--> 0 && (caseta [i] .style.color = 'roșu'));
De data aceasta, suntem puțin complicați cu in timp ce
buclă. Da, este un pic cam snarky, nu-i asa? În esență, am mimează:
var i = 0, len; pentru (len = box.length; i < len; i++ ) box[i].style.color = 'red';
Cu toate acestea, deoarece avem nevoie doar de o singură acțiune, putem salva câteva linii. Rețineți că lizibilitatea este mult mai importantă decât salvarea a două linii - prin urmare, referința mea "snarky". Cu toate acestea, este întotdeauna distractiv să vezi cât de condensat îți poți face buclele. Suntem dezvoltatori; facem astfel de lucruri pentru distracție! Oricum, nu ezitați să rămâneți cu pentru
versiune de declarație.
$ ()
În mod evident, intenția noastră este să nu replicăm întregul API jQuery. De obicei, pentru proiectele non-jQuery, $
sau $$
funcția este folosită ca o stenogramă pentru recuperarea unuia sau mai multor elemente din DOM.
var $ = funcția (el) return document.querySelectorAll (el); ; // Utilizare = $ ('. Caseta');
Observa asta $
este pur și simplu un indicator de un caracter la document.querySelector
. Economisește timp!
dacă (document.getElementsByClassName) document.getElementsByClassName = funcția (cl, tag) var els, matches = [], i = 0, len, regex = new RegExp cl + '(?: \\ s | $)'); // Dacă nu este specificat niciun nume de tag, // trebuie să luăm EVERY element din DOM els = document.getElementsByTagName (tag || "*"); dacă (! els [0]) return false; pentru (len = els.length; i < len; i++ ) if ( els[i].className.match(regex) ) matches.push( els[i]); return matches; // an array of elements that have the desired classname ; // Very simple implementation. We're only checking for an id, class, or tag name. // Does not accept CSS selectors in pre-querySelector browsers. var $ = function(el, tag) var firstChar = el.charAt(0); if ( document.querySelectorAll ) return document.querySelectorAll(el); switch ( firstChar ) case "#": return document.getElementById( el.slice(1) ); case ".": return document.getElementsByClassName( el.slice(1), tag ); default: return document.getElementsByTagName(el); ; // Usage $('#container'); $('.box'); // any element with a class of box $('.box', 'div'); // look for divs with a class of box $('p'); // get all p elements
Din păcate, metoda moștenirii nu este chiar atât de minimă. Sincer, în acest moment ar trebui să folosiți o bibliotecă. jQuery este foarte optimizat pentru a lucra cu DOM, motiv pentru care este atât de popular! Exemplul de mai sus va funcționa cu siguranță, dar nu suportă selectori complexi de CSS în browserele mai vechi; acea sarcină este doar un balon mai complicat!
Este important să observ că nu vă încurajez să renunțați la jQuery. Îl folosesc în aproape toate proiectele mele. Acestea fiind spuse, nu este întotdeauna dispus să îmbrățișeze abstractizările fără a lua puțin timp pentru a cerceta codul de bază.
Aș dori ca această postare să servească drept document viu, de felul. Dacă aveți oricare dintre dvs. (sau îmbunătățiri / clarificări pentru exemplele mele), lăsați un comentariu mai jos și voi actualiza sporadic această postare cu elemente noi. Marcați această pagină acum! În cele din urmă, aș dori să trimit un exemplar pentru acest set de exemple, care au servit drept impuls pentru acest post.