Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

FireFox et la navigation dans le Dom (firstChild, ChildNodes etc...)

 La plupart du temps, IE nous embete la vie pour faire ce qu’on veut dans nos pages web, surtout au niveau CSS …

Mais me voila contraint de constater que IE est, pour une fois, plus logique que Firefox !!! regardons de quoi je parle.

<h2>
          <a href="#" onclick="alert(this.parentNode.firstChild == this);">Click</a>
</h2>

On s’attend évidement à avoir true, pour une fois, je repete : POUR UNE FOIS, IE est plus logique que Firefox car IE retourne true alors que Firefox retourne false … 36_1_44

Le pourquoi de tout ca ? j’en savais encore rien … bizarre car le parentNode et firstChild sont bien des fonctions du w3c 


 Edit :

Aurélien m’a expliqué le problème : Ce problème du moteur GECKO est bien connu et l'explication vient de espace insécable. Effectivement, l'indentation de ton code perturbe GECKO qui comptabilise une TextNode pour le Tab d'indentation”. Pour résoudre ca il suffit de faire :

 <h2><a href="#" onclick="alert(this.parentNode.firstChild == this);">Click</a></h2>

C’est bien joli, mais bon quand on a plusieurs kilomètres de code on aimerait bien pouvoir rendre lisible tout ca. Aurélien aurait pu s’arreter làmais non, voici ce qu’il m’a proposé.36_1_11

var ie = /MSIE/.test(navigator.userAgent);
var moz = !ie && navigator.product == "Gecko";

if (moz) {
     HTMLElement.prototype.__defineGetter__(
"children", function() {
           var arr = new Array(), i = 0, l = this.childNodes.length;
           for ( i = 0; i < l; i++ ) {
               if ( this.childNodes[ i ].nodeType == 1 ) {
                    arr.push(
this.childNodes[ i ] );
               }
           }
      return arr;
      });

      HTMLElement.prototype.__defineGetter__(
"firstChild", function() {
            var node = this.childNodes[ 0 ];
            while (node.nodeType != 1) node = node.nextSibling;
                 return node;
            });

     HTMLElement.prototype.__defineGetter__(
"lastChild", function() {
     var node = this.childNodes[ this.childNodes.length - 1 ];
     while (node.nodeType != 1) node = node.previousSibling;
           return node;
      });
}

Ce que le code fait ? il redéfinit les fonctions “children, firstchild, lastchild” pour Firefox, comme ca elles ont le meme comportement que sur IE. On a mis children plutot que childNodes car pour définir children il faut faire appel à childNodes, il y aurait donc eu une référence circulaire.

Pour voir d’autres redefinition de fonction, il y a ce site qui en fait un bon paquet : http://webfx.eae.net/dhtml/ieemu/

Merci Aurélien

 Pour me venger, et surtout pour ne pas laisser dire à certains que IE c’est mieux que Firefox, je vous montre un des nombreux exemples où IE fait n’importe quoi (bien que dans ce cas, il fait pas n’importe quoi puisqu’il ne fait rien) …
           .C .content :first-child h2{margin-top:0px;}
Je ne parle pas des selecteurs CSS +,  >, :hover !important etc… que IE ne connait pas non plus

Pour conclure, je dirais que Firefox, contrairement à ce que beaucoup pretende n’est pas parfait, et que IE est loin de l’être aussi. Pour ce qui est de la gestion des CSS : Firefox est largement devant IE, alors qu’en ce qui concerne Javascript, IE semble un peu devant …  

Posted: mardi 12 avril 2005 18:57 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

cyril a dit :

Salut Cyril,

Ce problème du moteur GECKO est bien connu et l'explication vient de espace insécable.

Effectivement, l'indentation de ton code perturbe GECKO qui comptabilise une TextNode pour le Tab d'indentation, pour preuve, cet exemple qui résouds ton soucis :

<h2><a href="#" onclick="alert(this.parentNode.firstChild == this);">Click</a></h2>

Effectivement, lorsque tout le code est collé, on récupère bien true sur le test JavaScript.

Alors, la solution, ne plus indenté ton code en attendant que les 2 interpreteurs réagissent de la même façon :)
# avril 12, 2005 19:01

cyril a dit :

5 4 3 2 1 Troll IGNITION

I repeat Troll IGNITION :D
# avril 12, 2005 19:07

cyril a dit :

J'ai remarqué ça aussi sous FireFox et en chippottant un peu je me suis rendu compte que comme l'as dit Cyril le fait de tout mettre sur une ligne arrangeait l'affaire...

Maintenant j'ai une explication Merci :-)
# avril 12, 2005 19:23

cyril a dit :

Merci Aurélien
# avril 12, 2005 19:47

cyril a dit :

En fait, j'ai même mieux :-D

En rentrant, j'ai eu une illumination dans la voiture, je me suis souvenu d'une proposition d'Eric Meyer sur la redéfinition des Getter / Setter de GECKO afin d'implémenter quelques fonctionnalités propres à Internet Explorer.

Il suffit donc de modifier le Getter firstChild de façon à ce qu'il ne contabilise pas les TextNode de type saut a la ligne ( 10 ) et Tabulation ( 9 ).

J'ai essayé de l'implenter directement sur HTMLElement, mais il semblerai que ca coince, je vais me renseigner afin de pouvoir génériser l'idée, mais dans ton cas, la redéfinition du Getter firstChild sur HTMLHeadingElement produira le même effet que la non-indentation de code. Voici un exemple concret bcp plus parlant :

<html>
<head>
<script type="text/javascript">

var ie = /MSIE/.test(navigator.userAgent);
var moz = !ie && navigator.product == "Gecko";

if ( moz ) {

HTMLHeadingElement.prototype.__defineGetter__("firstChild", function () {
var i = 0; l = this.childNodes.length;
for ( i = 0; i < l; i++ ) {
if ( !( this.childNodes[ i ].nodeType == 3
&& ( this.childNodes[ i ].nodeValue.charCodeAt(0) == 10
|| this.childNodes[ i ].nodeValue.charCodeAt(0) == 9 ) ) ) {
break;
}
}
return this.childNodes[ i ];
});

}

</script>
</head>
<body>
<h2>
<a href="#" onclick="alert(this.parentNode.firstChild == this);">Click</a>
</h2>
</body>
</html>

Bon Dev ...

PS: Je vais continuer à chercher pour pouvoir implémenter cela sur tout les types d'éléments, je te tiens au courant.
# avril 12, 2005 20:49

cyril a dit :

Arrf, sacré moi, la textbox ne produit pas le plus bel effet :)

N'oubliez pas de ré-indenter le code ;-)
# avril 12, 2005 20:55

cyril a dit :

Juste en passant, même si le comportement de Firefox ne te semble pas logique, il est néanmoins conforme à la spécification du W3C.
Donc IE a tort sur ce coup là...
# avril 13, 2005 12:19

cyril a dit :

Sébastien,

Le plus important n'est pas de savoir qui a tort ou raison mais de répondre à une fonctionnalité avec une solution multi-navigateurs.

Au passage, tu aurais le lien expliquant tout cela sur le W3C, car j'ai beau chercher, je ne trouve rien concernant les explications du parsage des TextNode sur le DOM-Tree.
# avril 13, 2005 13:47

cyril a dit :

var ie = /MSIE/.test(navigator.userAgent);
var moz = !ie && navigator.product == "Gecko";

Cette partie me semble louche, qu'est-ce qui se passe si on change l'userAgent ? Pire, qu'est-ce qui se passe dans Opera ou Safari ?

AMHA ce n'est pas non plus une très bonne idée de réutiliser les mêmes noms de fonction que ceux du DOM qui ont un comportement prédéfini, sinon la relecture du code va devenir très difficile.

On peut toujours utiliser une bête fonction comme ça :

function firstNonTextChild(parent) {
var node = parent.firstchild();
while (node.nodeType == 3) {
node = node.nextSibling;
}
return node;
}
# avril 13, 2005 13:50

cyril a dit :

Salut Benoit,

Pour cet exemple, je reponds à une problématique IE / Gecko, je n'allais pas mettre tout un BrowserSniffer pour quelques lignes de code.

Concernant la modification du userAgent, que peut on faire contre les spoofer ??? Personnelement, je pense que l'on ne peut rien faire, si j'ai envie de modifier mes entêtes pour faire croire que mon IE est un FF, libre à moi de le faire et d'en accepter les conséquences, tout comme si je désactive le Scripting Engine ...

Concernant la fonction, pourquoi pas, le résultat sera effectivement identique.
Pour ma part je reste partisan de la modification du modèle DOM mais cela ne reste que mon avis.
# avril 13, 2005 17:42

cyril a dit :

Sebastien, j'aimerais moi aussi avoir les liens qui dit ce que doit faire childnodes etc...

Moi ce que j'ai c'est :

childNodes of type NodeList, readonly

A NodeList that contains all children of this node. If there are no children, this is a NodeList containing no nodes.

>>> http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1451460987

En tout cas moi IE me semble plus logique, et puis il réagit comme le framework .net et comme beaucoup d'autres encore
# avril 13, 2005 22:08

cyril a dit :

Bonjour,

Cette utilisation de defineGetter et defineSetter permettant d'émuler le comportement de IE me semble des plus intéressantes. Est-ce que ces fonctions sont unique à Gecko, si oui, y a-t-il un equivalent chez les autres broseurs ?
# mai 11, 2005 20:31

cyril a dit :

Alors la, aucune idée !

c'est plus avec Aurélien qui faudrais voir ca :)
# mai 11, 2005 20:39

cyril a dit :

Je vois pas ou est l'erreur de gecko.

Et il n'y à pas besoins de javascript pour que ton code soit correct et indenté, il faut juste l'ecrire proprement

Dans ton code que tu ecrive entre des balise,
XX
ou
(blancblanc)
ou
(saut de ligne)
(saut de ligne)

c'est pareil, c'est du contenut.

en gros si je remplace tes blancs et t'est sauts de lignes par des X tu à ecrit ceci

<h2>XXXXXX<a href="#" onclick="alert(this.parentNode.firstChild == this);">Click</a>XXXXXX</h2>

C'est pas très propre ;-)

ceci regle donc éféctivment le problème
<h2><a href="#" onclick="alert(this.parentNode.firstChild == this);">Click</a></h2>

maintenant si tu veux indenter ton code il suffit de mêtre tes espaces et saut de lignes et autres tabulations aux bons endroits, voici ce que ça donne:

<h2
><a href="#" onclick="alert(this.parentNode.firstChild == this);">Click</a
><h2
>

un autre exemple, plus complet:
<html
><head
><title>FireFox et la navigation dans le Dom (firstChild, ChildNodes etc...)</title
><meta content=".Text" name="GENERATOR"
><link id="MainStyle" type="text/css" rel="stylesheet" href="/skins/AnotherEon001/style.css"></link
><head
><body
><div
><table
><tbody
><tr
><td>AAAAA</td
><td>BBBBB</td
></tr
><tr
><td>CCCC</td
><td>DDDD</td
></tr
></tbody
></table
></div
><br
/><hr
>patatipatata<br
/><body
><html>
Des explications plus détaillé sur les ChildNodes, ainsi que des posibilité de tests, sont disponible ici :
http://www.chouette.info/testdom/

voila.
# mai 28, 2005 20:21

cyril a dit :

Sauf qu'evidemment, mais blanc en début ligne sont justement coupé, sur ton site.
du coup l'exemple n'est plus très explicit :-(

Bon ben je suppose que tu pourras imaginer malgrès tous.
# mai 28, 2005 20:25

cyril a dit :

Oui j'ai bien compris le problème, mais moi dans du xml

<truc>
texte
<tt>blabla</tt>
</truc>

ben quand je fais un firstChild de truc, je veux aller sur la balise tt et non sur texte, je sais que c'est le comportement préscrit par le W3C, mais je trouve ca stupide !


et puis la facon dont tu ecris le code, désolé mais je ne suis pas du tout d'accord avec cette idée. Ca nous fait pas du html très propre.

Maintenant que je sais que Firefox a un comportement, que je trouve plus stupide (bien que conforme w3c), je fais en sorte de plus avoir de problème, et je regarde si nodeType == 1
# mai 28, 2005 21:14

cyril a dit :

Euh, sinon, pour eviter les nodes texte avec du contenu inutile dedans, le DOM prévoit document.documentElement.normalize(), qui résout le probleme. Sinon bien sur la fonction proposée par aurélien marche bien.

Pour cyril, je pense que tu n'as pas bien compris ce que c'est que le DOM. Toi tu veux ptet que firstChild aille sur le premier element, mais ya des gens que ca interesse de recuperer le texte aussi, qui est une node aussi, et qui peut contenir des trucs sympas aussi... D'ailleurs, dans ton cas, IE a le meme comportement que firefox.
# juin 8, 2005 16:18

cyril a dit :

Oui, je sais ce que c'est que le DOM, et je comprend, mais pour moi du texte c'est pas un noeud. Mais c'est un choix que je comprend meme si je n'approuve pas.

pour moi un noeud c'est des balises pour recuperer l'interieur d'un noeud on a innerText (ou un truc du genre)

mais bon, maintenant que je le sais et que je connais la propriété nodeType tout est "OK" je continue à faire comme ca.

Par contre je ne connaissait pas document.documentElement.normalize() merci :)
# juin 8, 2005 16:26

cyril a dit :

Cyril, comment peut-on être "Certified" en quoi que ce soit si on ne comprend les outils que l'on utilise ?

Apprend XML, apprend le DOM et applique.

Maintenant pour tes soucis de scripting, commence par "faire du propre" en faisant des "unobtrusive scripts" (en gros, que des <script src="..."> et aucun attribute "ontruc". Du coup tu t'en fiches pas mal d'avoir besoin d'une fonction "getFirstChildElement".

Va voir aussi du côté des MochiKit, jslib et autres.

Bon, pis à part ça, je comprend vraiment pas l'intérêt de ton script, mais bon...
# octobre 4, 2005 00:16
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- SharePoint 2013: Préparation de la migration - Création des site Templates dans 2010 et 2013 par Blog Technique de Romelard Fabrice le 08-20-2014, 16:31

- [ #Yammer ] How to change interface language ? Comment changer la langue de l’interface ? par Le blog de Patrick [MVP SharePoint] le 08-20-2014, 14:21

- Onedrive Sync Engine Host : CPU à 100% par Le petit blog de Pierre / Pierre's little blog le 08-06-2014, 22:22

- SharePoint : Bug sur la gestion des permissions et la synchronisation Office par Blog Technique de Romelard Fabrice le 07-10-2014, 11:35

- SharePoint 2007 : La gestion des permissions pour les Workflows par Blog Technique de Romelard Fabrice le 07-08-2014, 11:27

- TypeMock: mock everything! par Fathi Bellahcene le 07-07-2014, 17:06

- Coding is like Read par Aurélien GALTIER le 07-01-2014, 15:30

- Mes vidéos autour des nouveautés VS 2013 par Fathi Bellahcene le 06-30-2014, 20:52

- Recherche un passionné .NET par Tkfé le 06-16-2014, 12:22

- [CodePlex] Projet KISS Workflow Foundation lancé par Blog de Jérémy Jeanson le 06-08-2014, 22:25