11550 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

le problème est connu je crois, il s'agit de la différence d'interprétation de :

element.firstChild

Ou

element.childNode[0]

Par IE ou les autres navigateurs.


Je ré expose la chose, dans

<div id="identifiant_div">
<hn id="identifiant_a_trouver"></hn>

... etc...
</div>


On va bien pouvoir faire avec IE

var id_a_trouver = document.getElementById('identifiant_div').firstChild.id;

// Ou bien

var id_a_trouver = document.getElementById('identifiant_div').childNode[0].id;


Mais avec les autres navigateurs du fait du retour de chariot dans le code html il faudra :

var id_a_trouver = document.getElementById('identifiant_div').childNode[1].id;


Alors je me demandais s'il y avait une méthode un peu éprouvée pour atteindre ce premier enfant direct pour tous les navigateurs.

Merci d'avance
Modifié par Christian Le Bouler (05 Jul 2007 - 22:56)
bonsoir,

il est possible de 'contourner le problème ' on vérifiant le 'type du noued' venant en premier !

Si le type est de type "text" (if(balise.nodeType == 1 ) { faire quelque chose | ou non Smiley ravi } ...
Vu qu'on ne fera rien avec un 'white space' .. ( en général) !

if(element.firstChild.nodeType != 1) // super c'est pas un espace blanc 
 {
    on peut travailler sur le noeud 
}


On peut aussi utiliser (selon ce que l'on vaut faire) utiliser la valeur "no-wrap" de l'attribut 'white-space dans le Css ...!
Et attribuer cette valeur a un noeud (et ses descendants ) avant d'intervenir avac le Dom ( voir exemple de w3cschools

Voilà j'espère que cela pourra te donner des idées pour ton code Smiley cligne
kzone a écrit :


bonsoir,

il est possible de 'contourner le problème '



Oui j'imagine bien qu'il est possible de contourner le problème, ne serait ce qu'en testant si le firstChild a un id, Après tout un white space ne peut pas avoir d'attribut id puisque ce n'est pas une balise.

Pitain ça reste quand même vachement bourrin à l'ère du web 2.0

/me comprends vraiment rien à ce fichu javascript... C'est ecrit par des humains ou des extraterrestres ?
En passant par la valeur de l'id , s'il existe ou pas , il faudrait plutôt vérifier s'i retourne une valeur 'null' ou 'undefined' (pas certain pour la valeur à vérifier)

En test de condition :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<title>Untitled Document</title>
		<script type='text/ecmascript'>
		 
		 function lookFor() {
		 	var body = document.getElementById('body');
		 	
		 	if(body.firstChild.nodeType == 1) {
				var div = body.firstChild;
				alert('case 1  : ' + div.nodeName);
			}
			else {
				var div = body.firstChild.nextSibling;
				alert('case 2 : ' + div.nodeName);
			}
			
			
		 }
		 
		 window.onload = lookFor;
		</script>
	</head>
	<body id="body">
	<div id="mon_div">
	
	</div>
	</body>
</html>

retourne toujours la balise Div , quite à tester l'id par la suite ...
Bon je regarde ça,

juste pour m'acclimater aux bêbêtes nodeType, nodeName et toussa...

Bon sauf bizzarerie inattendue ça sent le résolu cette affaire...

Mais ça attendra vendredÿ Parce que je suis pas là demain.
Salut,

Dans ce cas précis, on peut envisager
var id_a_trouver = document.getElementById('identifiant_div').getElementsByTagName('*')[0].id;

Avec éventuellement un petit test sur document.all car getElementsByTagName('*') ne fonctionne pas sur IE < 6.
Salut,

Bon alors j'ai essayé tout ça... Avec scrutch, scrutch dans les cheveux et tout Smiley biggol

A kzone >

Ta solution marche super bien Smiley biggrin

Et rend le sujet parfaitement résolu

Donc merci Smiley cligne



A Julien >

Avant toute chose et du fond du coeur, Merci ! Smiley smile

C'est vrai que j'avais du lire, c'était il y a pas mal de mois je crois, cette formulation du

getElementsByTagName('*')


Mais ça m'étais sorti de la tête tout bêtement Smiley decu

En dehors de cette contrainte sur IE<6 on ne peut que reconnaitre la superbe élégance de ce code.

J'imagine que le test doit donner quelque chose comme :


if (document.all) {
var id_a_trouver = document.getElementById('identifiant_div').firstChild.id;
}

else {
var id_a_trouver = document.getElementById('identifiant_div').getElementsByTagName('*')[0].id;
}


Alors si j'ai bien tout suivi le sujet est doublement résolu ! Et de manière parfaite à chaque fois ! Smiley langue


Ben encore merci
Modifié par Christian Le Bouler (05 Jul 2007 - 22:53)
Bonjour,

Dans l'idée, c'est ça, mais j'écrirais plutôt ceci :
var div = document.getElementById('identifiant_div');
var el = div.getElementsByTagName('*')[0];
if (!el && div.all) {
	el = div.all[0];
}

var id_a_trouver = el.id;

Parce que :
- Je préfère tester la solution standard en premier, pour pouvoir enlever facilement l'alternative quand je n'aurai plus besoin du support de IE < 6
- Opera supporte document.all mais pour lui document.getElementById('identifiant_div').firstChild sera bien le noeud texte.
Salut,

Donc en remettant la chose dans le contexte où je voulais l'utiliser ça donne :

html

<div id="global_galerie">
<h3 id="urba.inc">Galerie "Urba"</h3>

<ul id="galerie_mini">
<li></li>
<li></li>
<li></li>
</ul>
</div>


Et javascript

// Récupération de l'id
var referent_galerie = document.getElementById('global_galerie');

var pre_galerie_en_cours = referent_galerie.getElementsByTagName('*')[0];

if (!pre_galerie_en_cours && document.all) {
	pre_galerie_en_cours = referent_galerie.firstChild;
}

var galerie_en_cours=pre_galerie_en_cours.id;



// Traitement
var referent_menu=document.getElementById('contenu_menu');

var lien_active_lightbox=document.createElement('div');

lien_active_lightbox.innerHTML='<h3>Options</h3><p><a href="?active_lightbox=oui&galerie='+galerie_en_cours+'">Activer lightbox</a></p>';

referent_menu.insertBefore(lien_active_lightbox,referent_menu.firstChild);



Mon souci c'était que
. la valeur de l'id concerné est générée en php et donc change suivant les documents.
. La balise à laquelle cet id est attribué est pour l'instant un <h3> mais que je souhaite pouvoir changer le niveau de titrage si besoin est sans problème pour le javascript.

Vala, vala Smiley smile
la méthode utilisée est assez crade, car il ne faut surtout pas se fier au navigateur (ex : document.all), je peux trèq bien en tant qu'intégrateur mettre plusieurs pavés de commentaires HTML avant le premier node HTML

donc il faut mieux passer par une fonction idoine qui fait le boulot mais proprement.

function getFirstChild(elm) {
   for (var i=0; i<elm.childNodes.length; i++) {
       var node = elm.childNodes[ i];
       if (node.nodeType==1) return node;
  }
return null
}
Gatsu35 a écrit :
la méthode utilisée est assez crade, car il ne faut surtout pas se fier au navigateur (ex : document.all), je peux trèq bien en tant qu'intégrateur mettre plusieurs pavés de commentaires HTML avant le premier node HTML

La méthode que je proposais ne se "fiait" pas au navigateur, merci de lire tous les messages avant de répondre.

Par contre, les commentaires posent en effet problème avec IE, qui les renvoie pour getElementsByTagName('*').