12

i以下のforループ内の変数へのアクセスを維持するにはどうすればよいですか?答えを得るだけでなく、学ぼうとしているので、少し説明しておくととても助かります。ありがとうございました!

var el, 
    len = statesPolyStrings.length;

for (var i = 0; i < len; i++) {
    el = document.getElementById(statesPolyStrings[i]);

    google.maps.event.addDomListener(el, 'mouseover', function() {
        $("#"+statesPolyStrings[i]).addClass("highlight");
        statesPolyObjects[i].setOptions({ strokeWeight: '2' });
    });
}
4

3 に答える 3

29

すべてのコールバックは同じi変数を共有します。
イベントハンドラーが実際に実行されるときiは、配列の終了後です。

ループ本体を、パラメーターとして受け取る自己呼び出し関数でラップする必要がありiます。
このようにして、各反復は独自の不変のi変数を取得します。

例えば:

for (var i = 0; i < statesPolyStrings.length; i++) {
    (function(i) {
        ...
    })(i);
}
于 2012-06-08T18:23:02.463 に答える
2

自己呼び出し関数のトリックはうまく機能します。それは新しいスコープ(おそらく「関数javascriptのスコープ」のグーグル)を作成し、したがってi別の変数として処理し、イベントリスナーのコールバック関数に正しい値を提供します。

ただし、実際には、jQueryを使用して要素を再度見つける必要はありません。これは、既にイベントリスナーを割り当てており、関数内に。を使用して要素への参照があるためthisです。

そして、とにかくjQueryを使用しているので、要素のIDと配列を渡すことでの正しいインデックス(your i)を簡単に見つけることができます(一意のIDを扱っていると仮定します。そうでない場合も失敗します。最初に見つけたものを取ります)。statesPolyObjects$.inArray()statesPolyStrings$("#"+statesPolyStrings[i])

var el;

for (var i = 0, len = statesPolyStrings.length; i < len; i++) {
    el = document.getElementById(statesPolyStrings[i]);

    google.maps.event.addDomListener(el, 'mouseover', function(event) {
        $(this).addClass("highlight");
        statesPolyObjects[$.inArray(this.id, statesPolyStrings)].
            setOptions({ strokeWeight: '2' });
    });
}

それでも自己呼び出し機能を使い続けたい場合は、とにかく次の行を変更する必要があります。

("#"+statesPolyStrings[i]).addClass("highlight");

$(this).addClass("highlight");

イベントに精通していない場合はthis、次の記事を読むことをお勧めします: http ://www.sitepoint.com/javascript-this-event-handlers/

event匿名のコールバック関数内にも引数を書いたことにお気づきかもしれません。console.logイベントリスナーのコールバック関数を使用して無料で配信されるこのイベントを試して、アクセスできる他のすべてのものを調べてください。たとえば、クリックした実際の要素を見つけることができますevent.target(実際のマウスオーバーは要素の子に発生した可能性があるため)。それで:

google.maps.event.addDomListener(el, 'mouseover', function(event) {
    console.log(event);
    ...

ブラウザのコンソールを開いて、どのイベントが配信されるかを確認してください...

google.maps.event.addDomListenerただし、それは別のことを通過しdocument.body.addEventListener、ブラウザ間にも違いがあることに注意してください。たとえば、jQuery.on()は、イベントオブジェクトでいくつかの異なるものを提供しますが、少なくともすべてのブラウザーで同じデータを信頼できます。

于 2013-09-08T11:19:02.837 に答える
1
for (var i = 0; i < statesPolyStrings.length; i++) {
    (function(i){
        google.maps.event.addDomListener(document.getElementById(statesPolyStrings[i]), 'mouseover', function() {
        $("#"+statesPolyStrings[i]).addClass("highlight");
        statesPolyObjects[i].setOptions({ strokeWeight: '2' });
        });
    })(i)
}
于 2012-06-08T18:24:03.433 に答える