REMARQUE ! Les informations sur cette page sont largement obsolètes. Pour obtenir des informations à jour sur le projet Mozilla, consulter la page de la communauté Mozilla francophone, leur blog principal et leur blog technique.
Ce qui suit est une liste de choses à examiner de sorte qu'une page web soit compatible, non seulement avec Mozilla, mais avec n'importe quel navigateur qui implémente les dernières normes.
Certains pourraient dire que créer une page compatible exige de faire le double d'effort, et que ce n'en vaut pas la peine puisque « tout le monde utilise Explorer ». Par cet article je veux prouver que ce n'est pas vrai. C'est pratiquement le même effort de faire une page compatible avec Mozilla qu'une qui ne l'est pas.
Je tiens à préciser que ce texte n'a pas l'intention de vous dire comment faire des pages compatibles avec le désuet Netscape 4. Ce serait certainement une tâche beaucoup plus grande . Cet article aspire à vous guider à supporter des navigateurs qui sont très semblables dans le support de choses comme le dynamique HTML, car ce n'est pas nécessaire d'avoir une page pour chaque sorte de navigateur, il est préférable de partager le code en tenant compte des petites différences. Les détails énumérés ici seront utilisés pour les navigateurs tel que Mozilla, Netscape 6/7, Konqueror, Opera, etc.
L'écriture de scripts. La grande majorité des problèmes de compatibilité tombe dans cette catégorie. Et ce ne sont pas généralement des problèmes avec le langage JavaScript lui-même, mais avec le fait que les navigateurs représentent la page dans des objets différents Une API différente, en quelque sorte.
Voyons maintenant quels sont les problèmes les plus communs...
 Une manière commune de faire face aux différentes versions des
 navigateurs est de détecter celui utilisé. 
 C'est généralement une mauvaise idée.
 Il est beaucoup plus recommandé, maintenable et facile de juste
 détecter chaque fonctionnalité désirée
 quand vous vous en servez. De cette façon vous supporterez
 automatiquement tous les navigateurs implémentant cette 
 fonctionnalité, et limiterez les chances de ne pas supporter un
 navigateur. Le Javascript est un langage très dynamique qui
 permet de demander si un objet a une certaine méthode ou
 propriété, ainsi il est simple de détecter les
 choses correctement. Pour vérifier l'existence d'une
 méthode ou d'une propriété dans d'un objet 
 évaluer simplement l'expression dans un contexte booléen.
 Par exemple, pour demander si la propriété
 prop existe dans l'objet  o 
 on un peut écrire : if(o.prop) {. 
Une autre erreur commune est de vérifier si le navigateur a
quelque chose et s'il ne l'a pas supposer qu'il a une autre chose.
Le cas typique implique document.layers (les
désuets et épouvantables layers de l'API inclut à
Netscape 4). Beaucoup de pages supposent que si un navigateur n'a pas
document.all il est sûr de supposer qu'il
supporte l'autre interface. On ne peut pas compter dessus. C'est mieux 
de directement tester ce que l'on va utiliser.
 Explorer 4 a introduit ce qui s'appelle le dynamique
 HTML.
 Il est utilisé pour modifier la structure de la page à
 partir du Javascript. Comme dans cette API il y avait déjà
 beaucoup de choses dépendant du document  (tel que 
 document.forms   document.images  etc. ), 
 quelqu'un de Microsoft  a dit :
― Où mettons-nous TOUS LES AUTRES ?
― Je sais ! Dans
document.all
 Plus tard,  le W3C a
 créé une fonction pour cela : 
 document.getElementById(id).
 Elle est supportée dans Explorer depuis la version 5. 
 Que faisons-nous avec les utilisateurs IE4 ? Quelle bonne question !
 Une solution élégante est de créer la fonction, Javascript est si 
 dynamique qu'il permet d'attacher une nouvelle fonction au document !
 Ajouter ceci tout au début du script :
if(!document.getElementById && document.all)
    document.getElementById = function(id) {
        return document.all[id];
    }
else if(!document.getElementById && !document.all)
    document.getElementById = function(id) {
        // Très vieux navigateur. Nous faisons cela pour que object.style continue
        // à fonctionner (mais sans faire n'importe quoi)
    return { style: {} };
    }
Après que ce code soit exécuté dans IE4 document.getElementById
est une variable qui contient une fonction qui implémente la fonction
standard.
 Maintenant la chose  à faire est  juste  de remplacer partout
 de la manière suivante : Là où vous voyez 
 document.all.theMenu.style.color="black " changez le par
 findObject("theMenu").style.color="black" .
 Dans la représentation JavaScript d'une page web il y a
 plusieurs tableaux. Et les tableaux sont censés être
 accédés avec[ ]. Microsoft a le concept de
 collections dans ses langages de script, qui est une
 variation du même sujet, mais ces collections sont consultée avec
 (). Ils ont eu l'idée terrible de transférer
 ceci dans leur implémentation de Javascript, ainsi
 document.forms(0) fonctionne dans Explorer, mais pas dans
 les autres navigateurs. On doit toujours utiliser [],
 c'est-à-dire :
 documents.forms[0].field.value
 et document.images[0].
 Au début, le traitement d'un  événement  était 
 juste mettre un petit peu de code quelque part dans l'attribut 
 onclick . Netscape a étendu cela pour que l'on
 puisse dans ce petit morceau de code, avoir accès à
 une variable event.  Dans un telle variable on peut
 trouver la plupart des détails intéressants comme quelle
 touche a été pressée et d'autres choses.
 
Quand Microsoft est entré en scène ils ont pensé :
― Dans quel objet cette variable
eventdoit-elle être pour qu'elle soit disponible dans le bout de code ?― Mettons-la dans
window, pour qu'elle reste accessible à tout ce qui est dans l'omniprésent objetwindow
 Et l'horrible window.event est né, qui allait devenir 
 une sorte de variable globale. 
 Ce  window.event, en plus d'être une idée
 épouvantable, ne fait pas partie du standard  (heureusement).
 Donc le seul endroit fiable dont on est certain d'avoir accès 
 à l'événement est dans l'attribut 
 on event. À cette endroit il y a une
 variable appelé event. Si une fonction est
 appelée, event doit être passé 
 comme un paramètre. Exemple : 
  <a onmouseover="mouseOver(event) "...
Une utilisation légèrement plus avancée des
événements consiste à assigner des fonctions
à certaines propriétés des objets que vous
voudriez surveiller, par exemple :
findObject("monLien").onmouseover=maFonction;.
Dans ce cas le mécanisme expliqué dans le paragraphe
précédent n'est pas appliqué. À la place,
les navigateurs compatibles avec
les standards d'événement du DOM
 passeront l'événement comme paramétre à
 la fonction myFunction qui pourrait être défini 
 de la manière suivante :
function myFunction(e)
{
  // n'oublions pas le pauvre Explorer
  // qui ne passe pas l'événement comme paramètre
  if(!e)
    e=window.event;
    // reste du  code
    // ...
}
La section précédente a couvert les mécanismes nécessaires pour obtenir l'objet qui représente un événement. Mais la question ne finit pas là, puisque les propriétés définies dans Explorer ne sont pas les mêmes que les propriétés que les standards prescrivent (c'est-à-dire ceux implémentées par Mozilla ).
| dans Explorer | Description | Dans Mozilla (DOM standard) | 
|---|---|---|
| srcElement | L'élément qui a renvoyé l'événement. | La même, mais dans Mozilla les noeuds de type texte
    peuvent également renvoyer des événements,
    ainsi pour garder quelque chose qui fonctionne vous devrez remonter
    dans l'arbre jusqu'à ce que vous trouviez le noeud
    (la balise): d'un élément. 
     var node = e.srcElement;
     while(node.nodeType != node.ELEMENT_NODE)
     node = node.parentNode;
     | 
| fromElement | L'élément sur lequel la souris était avant. | targetsi l'élément  est onmouseout,relatedTargetsi l'élément  est onmouseover. | 
| toElement | L'élément sur lequel la souris a été déplacé. | relatedTargetsi l'élément  est onmouseout,targetsi l'élément  est onmouseover. | 
| cancelBubble | Assigner cette propriété à vrai empêche l'événement de continuer à se propager vers le haut dans l'arbre du DOM. | La méthode stopPropagation()de
    l'événement doit être appelé. | 
| returnValue | Si cette propriété est assigné à faux on demande à Explorer de ne pas exécuter l'action par défaut de l'événement (comme suivre un lien). | La méthode preventDefault()doit être 
     appelée. | 
| offsetX,offsetY | Position de l'événement en rapport avec l'élément qui l'a produit. | Si la souris est vraiment sur un 
    élément avec un positionnement fixe (fixed)
    ou relatif (relative), vous pouvez alors utiliser layerX,layerY(non standard). 
    Sievent.targetest dans un élément normalement positionné 
    (statique) ces propriétés vous donneront l'offset
    par rapport à la page. | 
Par l'arbre du DOM je veux parler de la structure hiérarchique des objets que le navigateur utilise pour représenter les balises qui composent la page. Il y a de petites différences qui peuvent affecter la compatibilité d'une page.
| Dans Explorer | Description | Dans Mozilla | 
|---|---|---|
| window.screenLeft,window.screenTop | Position de la fenêtre du navigateur relativement à l'écran. | window.screenX,window.screenY(voir l'exemple). | 
| contains(node) | Cette méthode est disponible dans chaque élément, et permet de demander si un autre noeud est un descendant de celui-ci. | Le DOM niveau 2 n'a pas de méthode équivalente, mais une méthode très 
    simple comme celle montrée ci-dessous peut être utilisée (cela
    fonctionne dans Mozilla et Explorer) : 
     // Découvre si  a est un ancêtre de b
     function contains(a,b)
     {
        // remonte par les parents de b
        // jusqu'à ce qeu nous en trouvions un
        while(b && (a!=b) && (b!=null))
         b = b.parentNode;
        return a == b;
     }
    Le nouveau standard DOM de niveau 3 définitnode.compareTreePosition()et Mozilla l'implémente déjà, mais pas Explorer. | 
| document.parentWindow | Cela donne la fenêtre dans laquelle se trouve le document. | document.defaultView.
    Notez que
    l'objetwindowest disponible partout. Elle 
    pourrait présenter un interêt dans des pages 
    utilisant des cadres (frames), mais je ne pense pas que l'abscence de
    cette propriété rende quoi que ce soit d'imposible. | 
| myForm | Accéde à un formulaire défini par <form name="myForm"> | Vous devez utiliser document.myForm | 
| element.innerText | Remplace le contenu de l'élément avec le texte indiqué. | Il n'existe aucun équivalent dans Mozilla, mais vous pouvez utiliser innerHTMLà la place, cependant le texte ne
    pourra pas contenir de<ou de&puisque le texte serait analysé comme du HTML, doncinnerHTMLpeut s'avérer dangereux à être utilisé (en plus ce n'est pas une propriété standard).
    Le meilleur remplaçant est de s'assurer qu'il y a un noeud enfant de 
    type texte à l'intérieur de element. C'est fait simplement
    en initialisant l'élément avec un espace à l'intérieur 
    comme ceci<div> </div>.
    Alors vous pouvez changer le texte facilement en faisantelement.firstChild.data = newText;. | 
(Site mise à jour le mardi 16 mars 2004)