jQuery semplifica di molto la gestione del DOM tramite JavaScript. Il DOM è una sigla che sta per Document Object Model, ossia modello a oggetti del documento. Un documento non è necessariamente un documento HTML, ma può essere scritto in qualsiasi linguaggio di marcatura supportato da un browser (XML, SVG, eccetera). Scopo di questo articolo è quello di chiarire alcuni aspetti legati al DOM e a jQuery.
Oggetti jQuery e oggetti DOM
jQuery, tramite il wrapper $()
, trasforma un oggetto del DOM in un oggetto jQuery, assegnandogli i metodi e le proprietà della libreria. Si può operare un processo inverso riconvertendo l'oggetto jQuery in un oggetto del DOM. Per esempio, data la seguente marcatura:
<div id="test" class="test"></div>
Quello che segue è un oggetto jQuery:
var test = $('#test');
Possiamo quindi usare i metodi di jQuery:
console.log(test.attr('class')); // 'test'
Ma non quelli del DOM:
console.log(test.className); // Errore!
Per farlo dobbiamo riconvertire l'oggetto in un oggetto del DOM:
var test = $('#test')[0];
console.log(test.className); 'test'
La sintassi è:
var domObject = $(jqueryObject)[0];
Questo passaggio è ancora più evidente nel caso dei metodi di jQuery che operano sugli elementi:
$('#test').click(function() {
var $test = $(this); // oggetto jQuery
var test = this; // oggetto DOM
console.log($test.attr('class')); // 'test'
console.log(test.className); // 'test'
});
In questo caso this
può operare sia come riferimento ad un oggetto jQuery che ad un oggetto del DOM.
Usare i metodi del DOM con jQuery
Perchè dovremmo usare i metodi del DOM con jQuery se esistono già quelli nativi della libreria? Semplice: i metodi del DOM vengono implementati nativamente nei browser con linguaggi come C++, quindi sono notevolmente più veloci di quelli di jQuery.
Prendiamo ad esempio il metodo getElementById()
:
var test = document.getElementById('test');
var $test = $('#test');
Apparentemente il risultato è identico, ma se analizziamo il codice della libreria noteremo che jQuery esegue un procedimento di scomposizione dell'espressione CSS passata al wrapper $()
. Infatti se il browser supporta le Selectors API, jQuery utilizza quelle, altrimenti il controllo passa all'engine Sizzle per l'elaborazione dell'espressione CSS tramite espressioni regolari.
A questo punto si potrebbe dire: noi vogliamo utilizzare i metodi di jQuery. Come facciamo se utilizziamo il DOM? Semplice: è sufficiente passare l'espressione DOM al wrapper $()
:
var $test = $(test); // ossia $(document.getElementById('test')
Pensiamo ad esempio al contesto dei selettori. Questa è una soluzione che io uso molto spesso:
var $p = $('p', document.getElementById('test'));
La migliore performance del DOM si rivela con il tipico esempio della proprietà innerHTML
(non facente parte delle specifiche ufficiali ma comunque assegnata da tutti i browser a ciascun oggetto di tipo HTMLElement
che la accetti).
La controparte jQuery è html()
, che però è meno performante della prima. Esempio:
var html = '';
var test = document.getElementById('test');
for(var i = 0; i < 1000; i += 1) {
html += '<p>' + i + '</p>';
}
test.innerHTML = html;
innerHTML
è più veloce perchè i browser utilizzano il loro parser HTML quando usiamo questa proprietà. E dato che in assoluto un parser HTML è forse il componente più veloce di un browser, è chiaro che questa proprietà è da preferire ovunque sia possibile utilizzarla.
Riassumendo: i metodi del DOM sono da preferire se la vostra esigenza primaria è la performance delle vostre pagine. Se avete ad esempio una tabella con 5000 righe, forse sarebbe opportuno valutare le possibilità offerte dal DOM.
Attenzione comunque: alcuni metodi del DOM, come ad esempio quelli relativi alla creazione di elementi e al loro popolamento, possono non essere così efficaci come i metodi di jQuery, soprattutto se pensiamo in termini di verbosità del codice. Esempio:
var test = document.getElementById('test');
var txt = document.createTextNode('Test');
test.appendChild(txt);
In jQuery invece:
$('#test').text('Test');
In questo caso risparmiamo molto codice utilizzando i metodi di jQuery.