- 締切済み
onclickの中のvar i
天才のプログラマーの皆様に質問です。 要素にonclickイベントを設定したいのですが、下記のコードの問題の行★★★について ご説明をいただけないでしょうか? htmlファイル---------------------------- <input type="button" id="card_0" value="?"> <input type="button" id="card_1" value="?"> <input type="button" id="card_2" value="?"> <input type="button" id="card_3" value="?"> jsファイル------------------------ var el=document.getElementsByTagName("input"); for(var i=0;i<el.length;i++){ console.log(i); // 0,1,2,3 el[i].onclick=function(){ flip(this.id.replace(/^card_/,"")); //関数を設定 正しく設定されている console.log(this.id.replace(/^card_/,"")); // 0,1,2,3 console.log(i); //★★★ 0,1,2,3ではなく、なぜか4が表示されてしまう flip(i)では動作しない flip(this.id.re...略)のthisはel[i]でも動作しません }; } function flip(n){ 略 }
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- pringlez
- ベストアンサー率36% (598/1630)
単純に変数がいつ評価されるかという問題なのですが、確かに少し難しいと思います。 元のあなたのコードだと、全コード中に「i」はfor文の中にあるものだけしか存在しません。で、onclick時にこの世のどこかの「i」を表示するという意味なので、for文の中で定義されているiをonclickされるたびに見に行くのです。 「el[i].onclick=function(){…」の部分を以下に変更してみてください。無名関数を返す関数をループごとに実行しているわけですが…自分で言っていても伝わらなさそうだと思います。関数を返す関数というものがそもそも概念的に難しいと思いますので最悪、今は分からなくてもいいと思います。もう少し勉強していけばそのうちわかるようになる日も来ると思います。 el[i].onclick = (function(n) { return function() { flip(n); } })(i);
- Picosoft
- ベストアンサー率70% (274/391)
> 昔に終わったfor文の中身(onclickの設定)は、昔に実行されないのでしょうか? 無名関数を使うと少しわかりにくいかもしれないので、無名関数を使わずに書き換えてみます。 function clickHandler(){ flip(this.id.replace(/^card_/,"")); console.log(this.id.replace(/^card_/,"")); console.log(i); }; var el=document.getElementsByTagName("input"); for(var i=0;i<el.length;i++){ console.log(i); // 0,1,2,3 el[i].onclick=clickHandler; //「クリックされたらclickHandlerを呼んでね」という設定をしているだけ。この時点ではclickHandlerは実行されない }
- Picosoft
- ベストアンサー率70% (274/391)
var el=document.getElementsByTagName("input"); for(var i=0;i<el.length;i++){ //JavaScriptでは、こう書いてもiはelと同じスコープになります console.log(i); // 0,1,2,3 el[i].onclick=function(){ //この無名関数はclickイベント発生時に実行されるので…… flip(this.id.replace(/^card_/,"")); console.log(this.id.replace(/^card_/,"")); console.log(i); //ここではclickイベント発生時のi(for文はとっくの昔に回り終わってるので4)を表示することになります }; }
お礼
早速のご回答ありがとうございます。 >ここではclickイベント発生時のi(for文はとっくの昔に回り終わってるので4)を表示することになります なんとなく理解できました。 ただ、昔に終わったfor文の中身(onclickの設定)は、昔に実行されないのでしょうか? for文は昔に終わっているのに、その中身はclickされた時に実行という矛盾(?)が、理解できていません。