Écrit par Neil Deakin
,
mise à jour par les contributeurs à MDC
.
Traduit par Chaddaï Fouché (19/07/2004), mise à jour par Julien Appert (17/06/2005) , Alain B. (04/04/2007) .
Page originale :
http://developer.mozilla.org/en/docs/XUL_Tutorial/Document_Object_Model
Attention : Ce tutoriel est ancien et n'est pas mis à jour. Bien que beaucoup d'informations soient encore valables pour les dernières versions de gecko, beaucoup sont aussi obsolètes. Il est préférable d'aller consulter cette page sur la version française de ce tutoriel sur developer.mozilla.org.
Le Document Object Model (DOM, modèle objet d'un document) peut être utilisé pour modifier les éléments XUL ou obtenir des informations à leur propos.
Le DOM est utilisé pour stocker l'arbre des n½uds XUL. Quand un fichier XUL est chargé, les balises sont interprétées et converties dans une structure hiérarchique de n½uds du document, un pour chaque balise et bloc de texte. La structure DOM peut être examinée et modifiée en utilisant des méthodes dédiées. Des éléments XUL spécifiques fournissent également des fonctions additionnelles pouvant être utilisées.
Chaque fichier XUL chargé aura son propre document affiché dans une fenêtre ou un cadre. Bien qu'il ne puisse y avoir qu'un seul document associé à une fenêtre à un moment donné, vous pouvez charger des documents supplémentaires en utilisant plusieurs méthodes.
Dans Mozilla, on peut accéder au DOM et le manipuler en utilisant JavaScript. Les divers objets DOM possèdent des fonctions accessibles par script, pourtant, il est important de noter que le DOM est une API qui est accessible par JavaScript. JavaScript lui-même n'est jamais qu'un langage de script pouvant accéder à ces objets parce que Mozilla fournit ces objets à l'utilisation.
Dans JavaScript, il existe un unique objet global toujours disponible. Vous pouvez vous
reférer aux propriétés et méthodes de l'objet global sans avoir à les qualifier avec un objet. Par
exemple, si l'objet global possède une propriété name
, vous pouvez changer
le nom avec le code name=7
sans avoir à spécifier l'objet à utiliser. Dans un contexte
de navigateur, la fenêtre est l'objet global. Il en va de même pour XUL. Naturellement,
l'objet global sera différent pour chaque fenêtre. Chaque cadre aura également un objet window
séparé.
On se refère souvent à la fenêtre en utilisant la propriété window
, bien que ce soit optionnel.
Quelquefois, cette pratique sert uniquement à clarifier la portée de la méthode à laquelle vous vous reférez.
Par exemple, les deux lignes suivantes qui ouvrent une nouvelle fenêtre, sont fonctionnellement équivalentes :
window.open("test.xul","_new");
open("test.xul","_new");
Lorsque vous déclarez une fonction ou une variable en tête de script, en dehors d'une fonction,
vous êtes en train de déclarer une propriété de l'objet global. En XUL, chaque fonction que vous déclarez
sera définie comme une propriété de l'objet window
. Par exemple, le code suivant affichera deux fois le texte
message dans une alerte.
function getText() {
return "Message";
}
alert(getText());
alert(window.getText());
De fait, si vous vouler accéder à des variables ou appeler une fonction déclarée dans un script utilisé
par une autre fenêtre, vous pouvez y accéder juste en utilisant l'objet window
de l'autre fenêtre. Par exemple,
si nous avions combiné les deux derniers exemples dans un seul fichier, nous pourrions appeler la
fonction getText
au sein de l'autre fenêtre (par ex. la fenêtre test.xul). Pour cela, nous pouvons faire la
chose suivante :
alert(window.opener.getText());
Chaque fenêtre possède une propriété opener
contenant l'objet window
l'ayant ouverte. Dans cet
exemple, nous récupérons la fenêtre responsable de l'ouverture et appelons la fonction getText
déclarée dans un script
situé dans celle-ci. Notez que nous qualifions la propriété avec l'identifiant window
uniquement pour
plus de clarté.
La méthode open()
de la fenêtre retourne également une référence à la nouvelle fenêtre, donc
vous pouvez appeler des fonctions de la nouvelle fenêtre à partir de l'ouvrante. Toutefois, il est important de noter
que la méthode open()
renvoie sa valeur de retour avant que la fenêtre soit complètement
chargée, donc les fonctions ne seront pas forcément disponibles pour autant.
L'objet window
n'est défini par aucune spéficication DOM, mais est quelquefois considéré, dans Mozilla,
comme faisant partie du DOM niveau 0, un nom utilisé par des développeurs pour se reférer aux fonctions assimilées
DOM avant que celles-ci ne soient ajoutées aux spécifications. Le document actuel affiché dans une fenêtre peut
être récupéré en utilisant la propriété window
du document. Depuis qu'elle est devenue la propriété
de la fenêtre la plus couramment utilisée, la propriété document
est habituellement utilisée sans
le qualifieur window
.
Mozilla founit divers objets de document en fonction de son type. Les trois documents principaux sont les HTMLDocument, XMLDocument et XULDocument, respectivement pour les documents HTML, XML et XUL. Évidemment, c'est ce dernier type de document qui est utilisé pour le XUL. Les trois types de document sont très similaires. Concrètement, ils partagent tous la même implémentation de base. Mais il existe des fonctions spécifiques à chacun de ces documents.
La méthode la plus courante pour récupérer un élément dans un document est de lui affecter un attribut
id
et d'utiliser la méthode getElementById()
du document. Nous avons ajouté
l'attribut id
à un certain nombre d'éléments dans la boîte de recherche
de fichiers. Par exemple, nous pouvons obtenir l'état de la case à cocher en utilisant le code ci-dessous :
var state = document.getElementById('casecheck').checked;
La valeur casecheck correspond à l'id
de la case à cocher définissant
la sensibilité à la casse. Une fois que nous savons si elle est cochée ou non, nous pouvons utiliser cette
indication pour effectuer la recherche. Nous pourrions procéder de façon similaire pour l'autre case à cocher,
ou n'importe quel autre élément qui a un attribut id
. Nous aurons par exemple besoin de
récupérer le texte dans le champ de saisie.
Il n'est pas nécessaire d'afficher la barre de progression et l'arbre de données vide quand la
boîte de dialogue pour la recherche de fichiers est affichée pour la première fois. Ceux-ci
ont été ajoutées de façon à ce que nous puissions les voir. Retirons-les maintenant, et
affichons-les seulement lorsque le bouton « Rechercher » sera pressé. Au départ, nous devons les
rendre invisible. L'attribut hidden
est utilisé pour contrôler la visibilité d'un élément.
Nous allons modifier la barre de progression de façon à ce qu'elle soit cachée au départ.
Nous allons aussi lui ajouter un attribut id
pour
qu'un script puisse y faire référence pour pouvoir la cacher ou l'afficher. Profitons-en pour cacher aussi
le séparateur et l'arbre des résultats, puisque nous n'en aurons besoin qu'après avoir
effectué une recherche.
<tree id="results" hidden="true" flex="1">
.
.
.
<splitter id="splitbar" resizeafter="grow" hidden="true"/>
<hbox>
<progressmeter id="progmeter" value="50%"
style="margin: 4px;" hidden="true"/>
Nous avons ajouté l'attribut hidden
et mis sa valeur à
true. L'élément est ainsi caché lors de sa première apparition.
Ensuite, ajoutons une fonction qui sera appelée quand le bouton « Rechercher » sera pressé.
Nous mettrons les scripts dans le fichier séparé 'findfile.js'. Dans une section précédente,
nous avons ajouté l'élément script
dans le fichier XUL. Si vous ne l'avez pas encore fait, faites-le maintenant, comme
ci-dessous. Nous ajouterons aussi un gestionnaire oncommand
au bouton « Rechercher ».
<script src="findfile.js"/>
.
.
.
<button id="find-button" label="Find"
oncommand="doFind();"/>
À présent, créez un autre fichier nommé 'findfile.js' dans le même répertoire que
'findfile.xul'. Nous ajouterons la fonction doFind()
dans ce fichier.
La balise script
de ce fichier XUL
peut contenir du code. Cependant, pour diverses raisons,
notamment pour de meilleures performances, vous devriez toujours mettre vos scripts
dans des fichiers séparés, excepté pour les courts morceaux de code qui peuvent
se trouver directement dans les gestionnaires d'événement.
function doFind()
{
var meter = document.getElementById('progmeter');
meter.hidden = false;
}
Cette fonction récupère d'abord une référence à la barre de progression en
utilisant son id
, progmeter. La
seconde ligne du corps de la fonction change l'état de hidden
pour rendre l'élément visible.
Finalement, ajoutons une boîte de dialogue qui affiche ce que nous sommes en train de rechercher. Évidemment nous n'en voudrons pas dans la version finale, mais ajoutons la maintenant pour nous assurer que quelque chose se produise.
function doFind()
{
var meter = document.getElementById('progmeter');
meter.hidden = false;
var searchtext=document.getElementById('find-text').value;
alert("Recherche de \""+searchtext+"\"");
}
Maintenant, avec cette boîte d'alerte placée ici, nous saurons ce qui se produit quand nous cliquons sur le bouton « Rechercher ». Nous pouvons ajouter du code pour obtenir aussi ce qui est sélectionné dans les listes déroulantes.
Chaque élément XUL possède un lot d'attributs, un lot de propriétés et un lot d'enfants.
flex="1"
est
un attribut flex
déclaré avec la valeur 1.hidden
d'un élément.Il est possible de manipuler dynamiquement les attributs, propriétés et enfants d'un élément en utilisant les méthodes du DOM.
Il est important de noter que les attributs et les propriétés sont deux choses différentes. Tout simplement car
le fait qu'un attribut avec un nom donné existe ne signifie pas qu'il existe une propriété correspondante ayant le
même nom. Pourtant, c'est souvent le cas. Par exemple, pour obtenir le flex
d'un
élément, vous pouvez utiliser la propriété flex
. Dans ce cas, le code implicite retourne simplement
la valeur de l'attribut. Pour d'autres propriétés, XUL accomplira des calculs plus complexes.
Vous pouvez manipuler les attributs d'un élément en utilisant l'une des méthodes suivantes :
getAttribute( nomAttribut )
hasAttribute( nomAttribut )
setAttribute( nomAttribut , valeurAdonner )
removeAttribute( nomAttribut )
Ces fonctions vous permettent d'obtenir ou de modifier la valeur d'un attribut à tout moment. Par exemple, pour
utiliser la valeur de l'attribut flex
, vous pourriez utiliser le code suivant :
var box = document.getElementById('uneboite');
var flex = box.getAttribute("flex");
var box2 = document.getElementById('uneautreboite');
box2.setAttribute("flex", "2");
Pourtant, l'attribut flex
a une propriété de script correspondante pouvant être
utilisée à la place. Ce n'est pas plus efficace, mais c'est légérement plus court à écrire. L'exemple suivant fait
la même chose qu'au-dessus, en utilisant la propriété flex
à la place :
var box = document.getElementById('uneboite');
var flex = box.flex;
var box2 = document.getElementById('uneautreboite');
box2.flex = 2;
Une fois que vous avez une référence à un élément, vous pouvez appeler les propriétés de cet élément. Par exemple,
pour obtenir la propriété hidden
d'un élément, vous pouvez utiliser la syntaxe element.hidden
où
"element" est une référence à l'élément. Notez que la plupart des propriétés listées dans la référence est en
corrélation avec les attributs communs des éléments. Il y a des différences, bien sûr, par exemple, alors que
getAttribute("hidden")
retournera la chaîne "true" pour un élément caché, la propriété
hidden
retournera une valeur true booléenne. Dans ce cas, la conversion de type est faite
pour vous, donc la propriété est plus commode.
Comme pour chaque document, l'objet "element" pour les éléments XUL n'est pas le même que pour des éléments HTML et XML. Chaque élément XUL implémente l'interface XULElement. Un élément XUL est un élément déclaré avec l'espace de nommage (namespace) XUL. Ainsi, les éléments XUL auront cette interface même s'ils sont ajoutés à d'autres documents XML, et les éléments non-XUL ne l'auront pas. L'interface XULElement possède un certain nombre de propriétés et méthodes spécifiques aux éléments XUL, pour beaucoup héritées de l'interface générique des éléments DOM.
Un espace de nommage est un URI qui spécifie le type d'élément. Voici quelques exemples :
<button xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
<button xmlns="http://www.w3.org/1999/xhtml"/>
<html:button xmlns:html="http://www.w3.org/1999/xhtml"/>
<html:button xmlns:html="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
Les espaces de nommages sont spécifiés en utilisant l'attribut xmlns
.
C'est une distinction importante. En fait, le texte utilisé pour le préfixe n'est pas significatif lorsqu'il détermine quel type d'élément est utilisé.
Le DOM fournit un certain nombre de fonctions relatives aux espaces de nommage, similaires aux fonctions de base.
Par exemple, la fonction getAttributeNS()
est similaire à la fonction getAttribute()
, excepté
un argument supplémentaire pouvant être fourni pour spécifier un attribut dans un espace de nommage spécifique.
Quelques éléments XUL disposent de leurs propres propriétés qui leurs sont spécifiques. Reportez-vous à la référence pour un guide complet des attributs et propriétés disponibles pour un élément.
Le DOM est une structure en arbre composé d'un unique n½ud racine avec ses enfants. Vous pouvez obtenir une
référence au n½ud racine en utilisant la propriété documentElement
du document. Le n½ud racine est
toujours un élément, mais ce n'est pas le cas pour tous les n½uds de l'arbre. Un élément correspond à une balise
dans la source XUL, mais vous pouvez également trouver des n½uds de texte, des n½uds de commentaire et quelques
autres types dans un arbre de document. Dans le cas de XUL, l'élément racine sera la balise
window
dans le document XUL. Chaque n½ud de l'arbre
peut avoir des enfants et ces enfants peuvent avoir des n½uds fils à leur tour. Comme le DOM est une structure
en arbre, vous pouvez naviguer au sein de cet arbre en utilisant une grande variété de propriétés.
Quelques méthodes, parmi les plus communes, sont listées ci-après :
Ces propriétés vous permettent de naviguer de diverses manières au sein d'un document. Par exemple, vous pouvez
obtenir un premier enfant d'un élément en utilisant la propriété firstChild
et ensuite, naviguer au sein
de tous ses enfants en utilisant la propriété nextSibling
. Ou vous pourriez accomplir la même chose en
parcourant les items du tableau childNodes listant tous les enfants.
Dans Mozilla, la dernière façon est plus efficace.
L'exemple suivant montre comment parcourir tous les enfants du n½ud racine :
var childNodes = document.documentElement.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var child = childNodes[i];
// faire quelque chose avec child
}
La variable childNodes contiendra les enfants de l'élément racine du document. Nous pouvons donc
utiliser une boucle for
pour parcourir les enfants, en accédant à chaque item comme pour un tableau.
Dans la prochaine section, nous découvrirons comment modifier le DOM.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.