2008
05-29
11:40
はじめに
昨日,相方 (お仕事的な意味で) に聞かれながらもすぐに答えられなかったので,復習の意味もこめてメモ.
問題
1 2 3 4 5 | <div id="target"> <div>A</div> <div>B</div> <div>C</div> </div> |
id="target" な div 要素内のそれぞれの div 要素に対してクリックイベントを登録したい...そんなとき,ついつい次のように書いてしまいます.(自分と相方(お仕事的な意味で)が.)
1 2 3 4 5 6 7 8 9 10 | <script type="text/javascript"> var divs = document.getElementById( 'target' ) .getElementsByTagName( 'div' ) ; for( var i = 0; i < divs.length; i++ ) { divs[i].addEventListener( 'click', function() { alert( i ); } ); } </script> |
このコードを実行すると,イベント登録したどの要素 (A,B,C とそれぞれ表示されるはず) をクリックしても,
3
なアラートしか表示されません.
一解決策
こんな風にしてみました.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <script type="text/javascript"> var divs = document.getElementById( 'target' ) .getElementsByTagName( 'div' ) ; for( var i = 0; i < divs.length; i++ ) { ( function() { var j = i; divs[i].addEventListener( 'click', function() { alert( j ); } ); } )(); } </script> |
それぞれの要素をクリックすると,
1
2
のようにアラートが表示されるかと.
解説
サイ本 は 4.3.1 項,最初の 2文がすべてを物語っていましたね.
C や C++、Java と異なり、JavaScript にはブロックレベルのスコープがありません。ある関数で宣言された変数は、どのブロックで宣言されたのかにかかわらず「関数全体」で有効です。
おわりに
ここしばらく jQuery (そういえば,1.2.6 が出てますね) を使ってばかりで意識すらしていない状況だったので,改めて勉強し直せました.
クロスブラウザ問題とか 1つのイベントリスナーを使い回すとかは,この際おいときましょう.



