Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Actualités

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

    View Cyril Durand's profile on LinkedIn

    hit counters

Quizz JavaScript : gestionnaire d'evenements et boucles

Mitsu à commencé il y a quelques jours une série de quizz sur .net, principalement sur C# et .net 3.5. A mon tour de lancer des quizz sur javascript et ASP.net.


Je cherche à créer 10 boutons dynamiquement, lorsque l'on click sur un bouton un messagebox s'affiche avec le numéro du bouton, voici le code utilisé : 

var div = $get('div1'); for (var i = 0; i < 10; i++){ var btn = document.createElement('button'); btn.appendChild(document.createTextNode('button N°' + i)); btn.onclick = function(){ alert('button N°' + i); } div.appendChild(btn); div.appendChild(document.createElement('br')); }

Les boutons sont bien ajoutés, mais lorsque je clique sur n'importe quel bouton j'ai toujours "button 10" d'affiché.

Untitled

Pourquoi ?  

Indice : le texte affiché est toujours "button N°10" alors que le texte du dernier bouton est "button N°9" ...

Réponse et explications dans quelques jours.

Posted: jeudi 9 août 2007 12:13 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

FREMYCOMPANY a dit :

Je peux répondre ? Je peux repondre ?

# août 9, 2007 13:50

simon ferquel a dit :

C'est une histoire de scope, tu peux faire éxactement le même exemple en C#. Une solution serait de faire:

for (var i = 0; i &lt; 10; i++){

   var curIndex = i;

   var btn = document.createElement('button');

   btn.appendChild(document.createTextNode('button N°' + i));

   btn.onclick = function(){

       alert('button N°' + curIndex);

   }

   div.appendChild(btn);

   div.appendChild(document.createElement('br'));

}

# août 9, 2007 14:01

FREMYCOMPANY a dit :

Euh, à ma connaissance, il n'y a pas de scope (ou closure) en C# mais je peux me tromper...

Tu traduirais ca comment en C# ?

# août 9, 2007 14:06

simon ferquel a dit :

avec des méthodes anonymes, tu as éxactement le même comportement:

for(int i=0;i&lt;10;i++)

{

 var btn = new Button{Text = "Button n°"+i.ToString()};

 btn.Click = delegate{MessageBox.Show("Button n°"+i.ToString());};

 stackPanel.Children.Add(btn);

}

Et la solution du problème en C# est la même.

# août 9, 2007 14:35

cyril a dit :

Simon l'explication est presque bonne mais la résolution ne fonctionne pas.

Avec ta solution tu auras toujours "button N°9" :-)

en C# il se peut que cela fonctionne mais je doute que cela fonctionne également avec des types références ... :-)

# août 9, 2007 14:37

simon ferquel a dit :

J'ai oublié un "+" quelque part, saurez vous le retrouver? ^^

# août 9, 2007 14:38

simon ferquel a dit :

En C# ca doit fonctionner à priori, même avec des types références, dès lors que tu instancie un objet à chaque passage de boucle (le compilo détecte le scope des variables utilisées et dans le cas de ma solution, il crée une instance de la classe générée par passage de boucle).

sinon ca, ca doit marcher, mais j'aurais aimé résoudre le problème "à la C#" ^^:

btn.mynumber=i;

btn.onclick = function(){

   alert('button N°' + this.mynumber);

}

# août 9, 2007 15:26

gldfdp a dit :

var div = $get('div1');

for (var i = 0; i &lt; 10; i++){

   var btn = document.createElement('button');

   btn.appendChild(document.createTextNode('button N°' + i));

   var s="button n° "+i;

   btn.onclick = function(){

       alert(s);

   }

   div.appendChild(btn);

   div.appendChild(document.createElement('br'));

}

# août 9, 2007 15:38

gldfdp a dit :

j'ai fait une erreur, ca ca marche:

<html>

<body>

<div id='div1'></div>

<script type='text/javascript'>

var div = document.getElementById('div1');

alert(div);

for (i = 0; i < 10; i++){

   var btn = document.createElement('button');

   btn.appendChild(document.createTextNode('button N°' + i));

   btn.onclick = new Function('alert(' + i + ');');

   div.appendChild(btn);

   div.appendChild(document.createElement('br'));

}

</script>

</body>

</html>

# août 9, 2007 15:57

cyril a dit :

Les solutions btn.myNumber et new Function('alert(' + i + ')'); fonctionnent.

Je déconseille la deuxieme solution car cela nécessite une éval ce qui est couteux ... Il existe enfin une derniere solution qui consiste à modifier le contexte de la fonction ... sauriez vous comment ?

# août 9, 2007 18:45

simon ferquel a dit :

dans la boucle:

var obj = new Object();

obj.index = i;

obj.callback = function()

{

  alert(this.index);

}

btn.onclick = function()

{

  obj.callback();

}

# août 9, 2007 19:19

cyril a dit :

Simon, ton code ne fonctionne toujours pas :p

Il existe une autre solution en utilisant les méthodes de l'objet function ... :-)

# août 9, 2007 19:45

christian a dit :

Ma réponse :

Pas possible avec SQL Server de faire çà :op

# août 9, 2007 20:04

FREMYCOMPANY a dit :

"Il existe une autre solution en utilisant les méthodes de l'objet function" : Alors la je vois pas... Comment call ou apply pourraient aider ? Ah moins que tu ne penses à bind ?

Sinon, pourquoi ce casser la tête, alors que

btn.onclick = (function(i) { return function() { alert(i) } })(i.toString())

# août 9, 2007 20:18

simon ferquel a dit :

C'est vraiment trop nul JS ^^

# août 9, 2007 20:31

cyril a dit :

bravo fremy : tu as trouvé la solution que je prefere :p

J'avais pas pensé à cette solution quand j'ai écrit mon précédent message alors que j'en ai parlé dans la solution ...

mais il existe quand meme une solution avec call/apply, solution que je détaillerais dans mon prochain quizz ;-)

# août 9, 2007 21:04
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- WPF : la gestion des dates (Label, TextBlock) par Pierrick's Blog le il y a 4 heures et 27 minutes

- [ASP.NET] - ASP.NET Generated Image par Aurelien's Blog - When ClientSide meets .Net le il y a 5 heures et 54 minutes

- Utiliser le SDK Open XML pour manipuler vos documents Office Open XML par Julien Chable le il y a 7 heures et 8 minutes

- [Silverlight] - Créer un contrôle réutilisable et des propriétés personnalisées. par Danuz le il y a 10 heures et 25 minutes

- Photosynth : Composez et partagez vos scènes ! par Blog technique de Nicolas Boonaert le il y a 10 heures et 29 minutes

- Comment d&#233;bugger un programme de g&#233;n&#233;ration de code utilis&#233; dans VS ? par Matthieu MEZIL le il y a 10 heures et 29 minutes

- Avoir une propriété sur l'object context qui renvoit les sous-entités par Matthieu MEZIL le il y a 10 heures et 41 minutes

- Sortie du SDK 1.1 de Visual Studio 2008 par Michel Perfetti [Miiitch] le il y a 13 heures et 16 minutes

- Skyfire, Silverlight sur votre mobile ! par alex# le il y a 13 heures et 32 minutes

- VSTSDB 2008 GDR CTP16 est arrivé par Noham Choulant le il y a 14 heures et 36 minutes