De la jQuery la JavaScript O referință

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..


Înainte de a începe

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);

1 - $ ( '# Container');

Acest apel pentru funcții va interoga DOM pentru elementul cu un id de recipient, și să creeze un nou jQuery obiect.

JavaScript modern

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.

Moştenire

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.


2 - . $ ( '# 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.

JavaScript modern

var lis = Document.querySelectorAll ('# container li');

querySelectorAll va reveni toate elemente care se potrivesc cu selectorul CSS specificat.

Limitări ale selectorului

Î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.

Moştenire

var lis = document.getElementById ('container'); getElementsByTagName ('li');

3 - $ ('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ă.

JavaScript modern

[]. 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.

Moştenire

var anchors = document.getElementsbyTagName ('a'); addEvent (ancore, "clic", fn);

4 - $ ("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.

JavaScript modern

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.

Moştenire

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.


5 - $ ( '# Caseta') addClass ( 'folie').;

jQuery oferă un API util pentru modificarea numelor de clasă pe un set de elemente.

JavaScript modern

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');

Moştenire

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?


6 - . $ ( '# Lista') următoare ();

lui jQuery Următor → metoda va returna elementul care urmează imediat elementul curent din setul înfășurat.

JavaScript modern

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ă.

Moştenire

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.


7 - $ (“
') .AppendTo (' organism ");

Pe lângă interogarea DOM, jQuery oferă și posibilitatea de a crea și injecta elemente.

JavaScript modern

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';

8 - $ (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.

JavaScript modern

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.

Moştenire

// 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ă.


9 - 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.

JavaScript modern

[]. 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.

Moştenire

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.


10 - $ ()

Î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.

JavaScript modern

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!

Moştenire

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!


rezumat

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.

Cod