11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,

J'ai essayé de changer le nom de balise (mettre div plutôt que span), de modifier le style.zIndex mais rien n'y fait, pour une raison que je ne comprends pas, lorsque ma balise est encapsulée dans ma balise de contenu je ne peux pas intercepter les événements dessus.

Voici le code de la page (Page du bug) :
<!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=utf-8">
	<title>Page Title</title>
	<style type="text/css" media="screen">
		.demoBox {position:absolute;background-color:#CCC; }
		.demoBar {overflow:hidden;font-size:10px;height:1.2em;color:white;background:#777;}
		.demoContent {font-size:11px;}
	</style>
	<script type="text/javascript" charset="utf-8">
		window.onload = function()	{
			var div1 = document.createElement("div");
		    div1.className = "demoBox";
		    div1.style.left = 10 + "px";
		    div1.style.top = 10 + "px";
		    div1.style.height = 100 + "px";
		    div1.style.width = 100 + "px";

		    var divTitre = document.createElement ("div");
		    divTitre.className="demoBar";

		   	var texte1=document.createTextNode("Titre div");
		    divTitre.appendChild(texte1);

			var coursType = document.createElement("span");
			coursType.innerHTML = "[Cliquez ici]";
			coursType.onclick = function() {alert("Clic intercepté");};

		    var divContenu=document.createElement("div");
		    divContenu.className="demoContent";
			divContenu.appendChild(coursType);
		    divContenu.innerHTML += "<bR>Test<bR>" ;

		    div1.appendChild(divTitre);
		    div1.appendChild(divContenu);
		    div1.appendChild(coursType);
		    document.body.appendChild(div1);
		}
	</script>
</head><body /></html>


Comme vous pouvez le voir sur la page, la première occurence de "Cliquer ici" ne réagit pas au clic alors que le seconde réagit. Ces deux occurences sont générées à partir du même code.

Merci d'avance pour votre aide
Modifié par ybart (15 Mar 2007 - 18:20)
Salut ybart,

Déjà première chose, je te suggère d'éviter les accents type "é".
Ensuite, même si ça n'est qu'une page de test, <body /> n'existe pas Smiley cligne

Bon celà étant dit, pour répondre à ta question :

au lieu de mettre ça :

var coursType = document.createElement("span");
coursType.innerHTML = "[Cliquez ici]";
coursType.onclick = function() {alert("Clic intercept");};

var divContenu=document.createElement("div");
divContenu.className="demoContent";
divContenu.appendChild(coursType);
divContenu.innerHTML += "<bR>Test<bR>" ; // <br /> !!!


je te suggère ceci :

var coursType = document.createElement("span");
coursType.innerHTML = "[Cliquez ici]";

var divContenu=document.createElement("div");
divContenu.className="demoContent";
divContenu.appendChild(coursType);
divContenu.innerHTML += "<br />Test<br />" ;
divContenu.firstChild.onclick = function() {alert("Clic intercepte");}


En espérant t'avoir aidé,
@plouche
Modifié par Ze Nenex (16 Mar 2007 - 19:43)
Salut,
Ze Nenex a écrit :
Déjà première chose, je te suggère d'éviter les accents type "é".
Ah bon, et pourquoi ?
Ze Nenex a écrit :
je te suggère ceci :

var coursType = document.createElement("span");
coursType.innerHTML = "[Cliquez ici]";

var divContenu=document.createElement("div");
divContenu.className="demoContent";
divContenu.appendChild(coursType);
divContenu.innerHTML += "<br />Test<br />" ;
divContenu.firstChild.onclick = function() {alert("Clic intercepte");}
Attention, il vaut mieux éviter innerHTML si ce n'est pas utile (préférer document.createTexteNode).

Et puis dans un document HTML, on écrit <br> (ou <bR>, pourquoi pas, puisque la casse n'a pas d'importance), contrairement au XHTML, où l'on écrit <br />.
a écrit :
Ah bon, et pourquoi ?

Parce que c'est la première chose qui a fait planter la page. Et pour le <br />, autant prendre les bonnes habitudes Smiley biggrin

a écrit :

Attention, il vaut mieux éviter innerHTML si ce n'est pas utile (préférer document.createTexteNode).

C'est évident. Je voulais simplement lui montré où était son erreur, à lui de faire le reste.
Ze Nenex a écrit :
Parce que c'est la première chose qui a fait planter la page.
Euh.. Non, si l'encodage est correctement spécifié.
Ze Nenex a écrit :
Et pour le <br />, autant prendre les bonnes habitudes Smiley biggrin
Justement non, ce n'est pas une bonne habitude à prendre si l'on utilise un doctype HTML. Smiley cligne
Modifié par Julien Royer (16 Mar 2007 - 20:24)
Merci beaucoup pour ces informations, je vais essayer immédiatement. Je vais aussi veiller à bien respecter les normes Smiley cligne .

Par contre, j'aimerais comprendre pourquoi il faut utiliser onClick sur firstChild et non sur mon élément, ce n'est pas la même chose ?
Merci ZeZenex, ta solution fonctionne bien, mais je ne comprend toujours pas pourquoi ce que j'ai fait ne fonctionnait pas.

Par contre je préfère éviter d'utiliser les entités HTML autant que possible, j'imagine que les asiatiques résolvent les problèmes d'encodages autrement, si ils ne veulent pas avoir leurs pages quadrupler en volume.

Normalement si le serveur envoie le header d'encodage correct, il ne doit pas y avoir de problème. Mais le serveur n'est peut-être pas configuré pour de l'UTF-8. Mais ceci ne concerne pas la question.
ybart a écrit :
Merci ZeZenex, ta solution fonctionne bien, mais je ne comprend toujours pas pourquoi ce que j'ai fait ne fonctionnait pas.


Selon moi, même si je ne connais pas la source réelle du problème, il s'agit de cette ligne :

divContenu.innerHTML += "<br />Test<br />"

Lorsque tu définis auparavent la méthode onclick à l'objet span, tu ne le fais que de manière programmatique, c'est à dire qu'aucun attribut onclick n'est crée. Par la suite, la méthode innerHTML force le navigateur à évaluer le contenu de divContenu qui présente certe un élément span, mais sans aucun attribut onclick, ce qui équivaut à onclick = null.

Le mieux est de suivre les conseils de Julien : le problème peut-être évité en créant des textNode et en évitant innerHTML.

ybart a écrit :
Par contre, j'aimerais comprendre pourquoi il faut utiliser onClick sur firstChild et non sur mon élément, ce n'est pas la même chose ?

Non du tout, puisque l'élément div auquel tu ajoutes l'élément span admet ce dernier comme premier noeud enfant (soit firstChild). et donc :
divContenu.firstChild

fait référence à ton élément span.

@plouche.
Salut ybart,

Comme l'a dit Ze Nenex cette ligne pose problème

divContenu.innerHTML += "<br />Test<br />"


C'est l'abrégé de

divContenu.innerHTML = divContenu.innerHTML + "<br />Test<br />"


Pour évaluer l'expression, le navigateur doit d'abord sérialiser le DOM de
divContenu et produire une chaine au format HTML. Dans ton cas le onclick
passe à la trappe parce qu'il a été ajouté en tant qu'évenement. (je sais pas
ce que ça aurrait pu donner avec un setAttribute)

Voici une alternative:


function appendHTML(elt, html) {
	var e = document.createElement("div");
	e.innerHTML = html;
	var c = e.firstChild;
	while(c) {
		elt.appendChild( c.cloneNode(true) );
		c = c.nextSibling;
	}
}


Cette fonction te permet de faire une insertion html en préservant le DOM
existant dans ton noeud. On crée un élément temporaire non rattaché
au document, on colle le html avec innerHTML puis on parcours l'élément
et on clone tous les noeuds avant des les appondre à l'élément voulu.

Dans ton cas tu pourrais écrire ceci:


    appendHTML(divContenu, "<br />Test<br />" );


Une autre remarque concernant ton code, tu ajoutes deux fois l'élément
coursType à ton DOM, c'est à dire qu'il y a deux références dans l'arbre
qui pointent sur un même élément !

Quelqu'un sait-il si c'est légal ? ou si il y à un clonage lors du appendChild ?
Modifié par dool (16 Mar 2007 - 22:40)
ybart a écrit :
Merci ZeZenex, ta solution fonctionne bien, mais je ne comprend toujours pas pourquoi ce que j'ai fait ne fonctionnait pas.

Bonjour,
Soit tu restes non standard jusqu'au bout et tu mets tout dans un innerHTML:

		window.onload = function()	{
document.body.innerHTML+=
"<DIV class='demoBar'>Titre div</DIV><DIV class='demoContent'>"
+"<SPAN onclick='alert(\"Clic intercepté \")'>[Cliquez ici]</SPAN>"
+"<BR>Test</DIV>"
		}

En mettant le charset qui va bien
Ou tu suis les conseils de julien
Modifié par chmel (16 Mar 2007 - 23:08)