[memo][javascript] ループとイベント登録
はじめに
昨日,相方 (お仕事的な意味で) に聞かれながらもすぐに答えられなかったので,復習の意味もこめてメモ.
問題
<div id="target">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
id="target" な div 要素内のそれぞれの div 要素に対してクリックイベントを登録したい...そんなとき,ついつい次のように書いてしまいます.(自分と相方(お仕事的な意味で)が.)
<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
なアラートしか表示されません.
一解決策
こんな風にしてみました.
<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>
それぞれの要素をクリックすると,
0
1
2
のようにアラートが表示されるかと.
解説
サイ本 は 4.3.1 項,最初の 2文がすべてを物語っていましたね.
C や C++、Java と異なり、JavaScript にはブロックレベルのスコープがありません。ある関数で宣言された変数は、どのブロックで宣言されたのかにかかわらず「関数全体」で有効です。
おわりに
ここしばらく jQuery (そういえば,1.2.6 が出てますね) を使ってばかりで意識すらしていない状況だったので,改めて勉強し直せました.
クロスブラウザ問題とか 1つのイベントリスナーを使い回すとかは,この際おいときましょう.
















![twitomonitor [ついともにた] twitomonitor [ついともにた]](http://www.iwa-ya.net/img/banner/twitomonitor.png)


