Il wrapper $()
di jQuery ha la capacità di selezionare gli elementi trasformando l'argomento passato in un'espressione. Questo funziona perfettamente con gli elementi HTML o XHTML noti. Per elemento noto si intende un elemento a cui il browser associa delle proprietà e dei metodi DOM predefiniti basandosi sul namespace di appartenenza o sulla DTD. Quando un elemento non è noto, la selezione jQuery funziona ancora, ma non è possibile utilizzare i suoi metodi sugli elementi selezionati, in quanto questi non posseggono delle caratteristiche associate. Questo è il caso degli elementi XML appartenenti ad un namespace creato da noi. Vediamo un esempio concreto.
Abbiamo questo documento XHTML servito come XML:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:p="http://www.ns.com/ns/p">
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="text/xml; charset=utf-8" />
</head>
<body>
<p:div>Test</p:div>
</body>
</html>
Il namespace viene associato all'URI http://www.ns.com/ns/p
ed ha come prefisso p
. Possiamo utilizzare il metodo getElementsByTagNameNS()
con jQuery:
console.log($(document.getElementsByTagNameNS('http://www.ns.com/ns/p', 'div'))); // [<p:div>Test</p:div>]
All'apparenza funziona perfettamente. Ora proviamo ad operare sulla selezione:
$(document.getElementsByTagNameNS('http://www.ns.com/ns/p', 'div')).each(function() {
console.log(this); //<p:div>Test</p:div>
this.setAttributeNS('http://www.ns.com/ns/p', 'class', 'test'); // funziona
$(this).addClass('foo'); // non funziona
});
L'elemento è generico ed il browser non può associargli la proprietà className
ed è per questo che il metodo addClass()
fallisce. Tra l'altro, essendo generico, l'elemento ha bisogno della regola CSS @namespace
per poter ricevere gli stili assegnatigli:
@namespace "http://www.ns.com/ns/p";
div[*|class="test"] {
color: blue;
}