7.1 Document Object Model

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

Introduction au DOM

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.

Récupérer des éléments

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.

Notre exemple de recherche de fichiers

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.

Source Voir

Le DOM des éléments XUL

Chaque élément XUL possède un lot d'attributs, un lot de propriétés et un lot d'enfants.

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 )
Renvoie la valeur de l'attribut 'nomAttribut'
hasAttribute( nomAttribut )
Renvoie true si l'attribut de nom 'nomAttribut' a une valeur
setAttribute( nomAttribut , valeurAdonner )
Fixe la valeur de l'attribut 'nomAttribut' à la valeur 'valeurAdonner'
removeAttribute( nomAttribut )
Supprime l'attribut '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.

Naviguer dans le DOM

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 :

firstChild
Référence au premier n½ud fils d'un élément
lastChild
Référence au dernier n½ud fils d'un élément
childNodes
Contient la liste des enfants d'un élément
parentNode
Référence au père d'un n½ud
nextSibling
Référence au prochain n½ud de même niveau
previousSibling
Référence au n½ud précédent de même niveau

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.