Developpez.com

Télécharger gratuitement le magazine des développeurs, le bimestriel des développeurs avec une sélection des meilleurs tutoriels

Developpez.com - Développement Web
X

Choisissez d'abord la catégorieensuite la rubrique :


Rendre du code javascript compatible multi-navigateurs

Date de publication : 16/06/2005 , Date de mise a jour : 16/06/2005


I. Présentation
II. Javascript, ECMA-262 et le W3C
III. Fonctions compatibles avec les différents navigateurs
IV. Exemple d'utilisation


I. Présentation

Malgré le fait qu'asp.NET a apporté une importante évolution dans la conception d'applications web, javascript reste incontournable.

Certaines fonctionnalités ne peuvent être effectuées par du code sur serveur, quelque soit le langage utilisé. Au mieux, l'évolution des langages fera apparaître de nouvelles syntaxes permettant d'effectuer des actions qui ne peuvent être exécutées autrement que par du javascript. Cependant, ces fonctionnalités, si elles apparaîssent un jour dans les langages serveur, généreront très certainement du javascript. Le javascript restera donc un des langages les plus importants pour les traitements sur le client.

Le javascript est relativement riche en termes de fonctionnalités et simple du côté de la syntaxe. Un script est par définition une suite d'instructions simples, peu structurées, permettant d'automatiser certaines tâches. De plus, un script n'est pas compilé, ce qui a comme désavantage d'augmenter le risque d'erreurs à l'exécution.

Il n'en reste pas moins que l'utilisation de javascript est un facteur important dans la réussite d'un site Internet grâce à la convivialité apportée, quelle soit dûe à des traitements rapides ou bien d'autres choses…


II. Javascript, ECMA-262 et le W3C

L'ECMA-Script est basé sur diverses technologies dont, entre autres, JavaScript (créé par Netscape) et JScript (créé par Microsoft). Le dévelopement de ce standard a débuté fin 1996. Ce standard a été adopté par l'assemblée générale de l'ECMA (European Computer Manufacturers Association) quelques mois plus tard. La deuxième version du standard a été approuvée en juin 1998.

La dernière version, l'ECMA-262 est approuvé en décembre 1999.

Toutefois, il convient de noter qu'une nouvelle version de la norme ISO/IEC-16262 a été proposée en 2002.

La liste des spécifications du standard est disponible à l'adresse http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf.

Le W3C (www Consortium), pour sa part, régit les normes concernant le Document Object Model. Ceci est disponible à l'adresse http://www.w3.org/TR/DOM-Level-2-Core/def-index.html.


III. Fonctions compatibles avec les différents navigateurs

Malheureusement les différents constructeurs n'ont pas implémenté les différentes fonctions de la même manière, voire ne les ont pas implémentées du tout. C'est pourquoi beaucoup de développeurs utilisent leurs propres fonctions.

Voici dès lors un exemple de ce que tout script devrait comporter (il existe d'autres écritures dont le résultat est identique) :

Fonctions javascript fondamentales
function checkBrowser() { this.ver=navigator.appVersion; this.dom=document.getElementById?1:0; this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom)?1:0; this.ie55=((this.ver.indexOf("MSIE 5.5")>-1 || this.ie6) && this.dom)?1:0; this.ie5=((this.ver.indexOf("MSIE 5")>-1 || this.ie5 || this.ie6) && this.dom)?1:0; this.ie4=(document.all && !this.dom)?1:0; this.ns5=(this.dom && parseInt(this.ver) >= 5) ?1:0; this.ns4=(document.layers && !this.dom)?1:0; this.ie4plus=(this.ie6 || this.ie5 || this.ie4); this.ie5plus=(this.ie6 || this.ie5) this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns5); return this; } bw = new checkBrowser(); if (!document.getElementById) { document.getElementById = getObjectById; } function getObjectById(ID) { var obj; if (bw.dom) return document.getElementById(ID); else if (bw.ie4) return document.all(ID); else if (bw.ns4) return eval('document.' + ID); } function getObjectByIdParent(ID) { var obj; if (bw.dom) return parent.document.getElementById(ID); else if (bw.ie4) return parent.document.all(ID); else if (bw.ns4) return eval('parent.document.' + ID); } function cancelBubble(netEvent) { if (document.all) { window.event.cancelBubble = true; } else { netEvent.cancelBubble = true; } }
Expliquons maintenant l'utilité de chacune de ces fonctions :

La classe checkBrowser contient toute une série de propriétés permettant d'obtenir des informations sur le navigateur par lequel le script est executé. A l'aide de ces propriétés il est ainsi aisé d'effectuer des traitements différents suivant le navigateur et sa version.

this.ver=navigator.appVersion;
Quelle est la version du navigateur ?

this.dom=document.getElementById?1:0;
La fonction getElementById est elle implémentée sur le navigateur ?

this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom)?1:0;
Le navigateur est-il Internet Explorer 6.0 ou équivalent (qui se présente comme IE 6.0)?

this.ie5=((this.ver.indexOf("MSIE 5")>-1 || this.ie5 || this.ie6) && this.dom)?1:0;
Le navigateur est-il Internet Explorer 5.0, équivalent ou supérieur ?

this.ie4=(document.all && !this.dom)?1:0;
Le navigateur est-il Internet Explorer 4.0 ?

this.ns5=(this.dom && parseInt(this.ver) >= 5) ?1:0;
Le navigateur est-il Netscape 5 ou supérieur ?

this.ns4=(document.layers && !this.dom)?1:0;
Le navigateur est-il Netscape 4 ou supérieur ?

this.ie4plus=(this.ie6 || this.ie5 || this.ie4);
Le navigateur est-il Internet Explorer 4.0 ou supérieur ?

this.ie5plus=(this.ie6 || this.ie5)
Le navigateur est-il Internet Explorer 5.0 ou supérieur ?

this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns5);
Le navigateur fait-il partie des navigateurs précités ?

Il ne reste, dès lors, plus qu'à implementer cette classe, ce qui se fait au niveau global par:

bw = new checkBrowser();
La plupart des scripts utilisent la fonction getElementById. Cette fonction n'est pas implémentée par tous les navigateurs, c'est pourquoi il est préférable de redéfinir cette fonction par notre propre fonction. Le script suivant vérifie l'existence de la fonction et la redéfinit en cas de besoin.

if (!document.getElementById) { document.getElementById = getObjectById; }
Ceci permet d'utiliser des scripts utilisant getElementById sans devoir les modifier. Effectivement la fonction getObjectById permet, suivant le navigateur, de renvoyer l'élément désigné et ce, selon la syntaxe adéquate.

function getObjectById(ID) { var obj; if (bw.dom) return document.getElementById(ID); else if (bw.ie4) return document.all(ID); else if (bw.ns4) return eval('document.' + ID); }
Bien entendu, il faut s'assurer que getObjectById existe bien sans quoi le problème n'est que reporté.

Il serait bon de faire de même lors de tout appel de fonction, c'est à dire vérifier son existence avant l'appel d'une fonction. Par exemple :

function test() { If (fonctionUtilisee) fonctionUtilisee(); else alert('Fonction inexistante, merci de prévenir le webmaster.'); }

IV. Exemple d'utilisation

Afin de montrer et d'expliquer comment rendre du code javascript compatible avec la plupart des navigateurs, prenons un exemple concret. Voici la partie html de la page qui nous servira d'exemple :

Partie html
<html> <head> <script language="javascript"> … </script> </head> <body> <div id="Test">Contenu</div> <input type=button text="Afficher / Cacher"/> </body> </html>
Comme on peut le voir, cette page ne contient que deux éléments : un div contenant un texte et un bouton. Ce dernier composant aura pour but de cacher ou d'afficher le div.

Pour faire cela, ajoutons un attribut onclick au bouton. La valeur de cet attribut est l'appel de la fonction qui effectuera le traitement.

<input type=button text="Afficher / Cacher" onclick="javascript:showhide('Test'); return false;"/>
Il est important de noter que le " return false ; ", qui se trouve après l'appel de la fonction, n'est pas une erreur ou un oubli lors d'un test. Il s'agit d'éviter la remontée d'évènements. Il est également possible de stopper la propagation à l'aide de la fonction cancelBubble précitée. Il est important également de noter que l'ECMAScript (le javascript standard) définit la méthode stopPropagation().

Voici le code des fonctions utilisées par la fonction showhide :

showhide et fonctions nécessaires
function getObjectStyle(obj) { if (!getObjectById) return; if (theObj = getObjectById(obj)) return theObj.style; } function hide(obj) { if (!getObjectStyle) return; if (theObj = getObjectStyle(obj)) theObj.display = 'none'; } function show(obj) { if (!getObjectStyle) return; if (theObj = getObjectStyle(obj)) theObj.display = 'block'; } function showhide(obj) { if (!getObjectStyle) return; if ( !show) return; if ( !hide) return; if (theObj = getObjectStyle(obj)) { if (theObj.display == 'none') show(obj); else hide(obj); } }
Comme on peut le remarquer, l'existence des fonctions est vérifiée avant tout appel à celles-ci.

Par ailleurs, le code est divisé en diverses fonctions, ce qui permet une meilleure lisibilité du code ainsi qu'une amélioration de la facilité de maintenance. Ainsi, si un nouveau navigateur apparaît et n'implémente pas la fonction getElementById par exemple, il suffit d'ajouter la méthode pour récupérer l'élément. Il n'y a donc que très peu de fonctions à modifier.



Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2005 Danse Didier. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Responsable bénévole de la rubrique Développement Web : Xavier Lecomte -