11550 sujets

JavaScript, DOM et API Web HTML5

Salut !

Bon, c'est pas un problème en soi, juste une curiosité présente sur les moteurs JS TraceMonkey et V8 (le code complet ne fonctionnant pas avec JScript et Carkan). Donc à tester sous Firefox-like ou Chromium-like.

En gros, le même code écrit de 2 manières légèrement différentes fonctionne correctement ou pas.

Le code en question (à insérer dans une page vierge) :

var Toto=function(){
	var toto=this;

	var init=function(){
		//on insère un nœud text dans le div qu'on insert dans le body
		document.body.appendChild(toto.appendChild(document.createTextNode('toto')));
		
		//on insère un nœud text dans le div...
		toto.appendChild(document.createTextNode('toto'));
		//...qu'on insert dans le body
		document.body.appendChild(toto);
	}
	
	init();
}

var init=function(){
	Toto.prototype=document.createElement('div'); //Toto hérite d'un noeud div
	var toto=new Toto(); //toto est donc une instance de Toto mais aussi de HTMLDivElement précédemment créé
}

window.addEventListener('load', init, false);


Le code est censé affiché 2 "toto". Toto est un objet héritant d'un nœud DOM (un div en l'occurrence). L'instance toto de Toto est donc un objet représentant une instance non seulement d'Objet, mais également (entre autre) de HTMLDivElement. Donc à même de pouvoir intégrer un nœud body.

Dans la méthode init de l'objet Toto, le premier appendChild ne pose pas de problème, tandis que le second (qui n'est qu'une décomposition du précédent appendChild sur 2 lignes) renvoi une erreur (Node cannot be inserted at the specified point in the hierarchy" code: "3 sous Firefox).

Et je me demandais simplement si quelqu'un avait une explication à ce comportement étrange.
Modifié par MacIntoc (12 Feb 2010 - 09:37)
Salut

MacIntoc a écrit :
le second (qui n'est qu'une décomposition du précédent appendChild sur 2 lignes

Faux, appendChild retourne l'élément passé en paramètre. Dans le premier exemple c'est le texte qui est ajouter au body et non toto.

Sinon j'ai pas d'erreur avec firefox 3.5...
Ah oui, exact. J'étais tellement sur de moi que j'ai même pas prit le temps de vérifier le code HTML que j'obtenais dans le premier cas Smiley biggol
Déjà, ça répond à la question.

Effectivement, sur Firefox 3.5 ça fonctionne, c'est que depuis la 3.6 que ça renvoi l'erreur... Ce qui amène à une seconde question : pourquoi ?

Je vais essayer de me renseigner là-dessus et je reviens ^^


Après test, il n'y a que la 3.6 qui renvoi une erreur, sur Minefield, ça fonctionne sans problème. Smiley edit Modifié par MacIntoc (12 Feb 2010 - 09:58)[/edit]
Ton document est en transitional ou en strict ?
Peut être que le version 3.6 est plus regardante... si on lit la DTD stricte on peut voir :

<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
<!ENTITY % lists "ul | ol | dl">
<!ENTITY % blocktext "pre | hr | blockquote | address">

<!ENTITY % block
     "p | %heading; | div | %lists; | %blocktext; | fieldset | table">

<!ENTITY % Block "(%block; | form | %misc;)*">
[...]
<!ELEMENT body %Block;>


Ton body ne peut pas contenir de noeud texte (#PCDATA) directement, alors qu'en transitional c'est autorisé :

<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*">
[...]
<!ELEMENT body %Flow;>
Nan, ça ne vient pas de là. Bien que je sois en xhtml 1 strict, l'insertion d'un nœud texte fonctionne bien (alors que ça ne devrait effectivement pas, selon la norme).

C'est ce cas qui est exécute par la ligne :
document.body.appendChild(toto.appendChild(document.createTextNode('toto')));

toto.appendChild, comme me la rappelé jo_link_noir, renvoi le nœud inséré (donc un nœud text) et body.appendChild insère bien ce nœud dans le body.

C'est quand j'essaye d'insérer le div (la ligne document.body.appendChild(toto);) qu'il me dit que toto n'a pas sa place dans le body. Hors toto est, entre autre, un nœud div.
MacIntoc a écrit :
C'est quand j'essaye d'insérer le div (la ligne document.body.appendChild(toto);) qu'il me dit que toto n'a pas sa place dans le body. Hors toto est, entre autre, un n&#339;ud div.


Smiley strike Bah non justement, si tu décompose l'expression cela te fait, en trois temps :

1 - document.body.appendChild(toto.appendChild(document.createTextNode('toto')));
2 - document.body.appendChild(toto.appendChild(noeudTexte));
2 - document.body.appendChild(noeudTexte);

Tu insère un noeud texte dans ton body, après je ne dit pas que le problème vient forcément de là, mais en tout cas tu la seule manipulation que tu fais sur ta div toto c'est lui attacher un noeud texte.[/strike]

EDIT : je viens de comprendre ton message, dsl... c'est ça de lire en diagonale.
Modifié par MonsieurY (12 Feb 2010 - 18:01)