36

私は、他の誰かから引き継いだ HTML および Javascript コードを少し使用しています。ページは 10 秒ごとに (非同期要求を介して) データのテーブルを再読み込みし、DOM コードを使用してテーブルを再構築します。問題のコードは次のようになります。

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function() {
        onStatusChanged(select, callid, anotherid);
    };
    td.appendChild(select);
}

onchangeただし、要素に対してイベントが発生すると、テーブル内のすべてのメソッドに<select>同じ値が渡されているように見えます (ループの各反復で、新しい個別の値が与えられていることを確認しました) 。onStatusChanged()<select>callidanotherid

これは、構文を使用してイベント ハンドラーを設定する方法の性質が原因で発生していると思われselect.onchange = function()ます。これがどのように正しく機能するかを理解していれば、この構文は onchange イベントのクロージャーをこれら 2 つの参照を参照する関数に設定し、最終的にはループの最後の繰り返しで設定されたものの最終値を持ちます。イベントが発生するcallidと、 andによって参照されるanotherid値は、個々の反復で設定された値ではなく、最後の反復で設定された値になります。

渡すパラメータの値をコピーする方法はありますonStatusChanged()か?

質問と受け入れられた回答をよりよく反映するようにタイトルを変更しました。

4

2 に答える 2

50

実際、ここでクロージャーを実装する必要があります。これはうまくいくはずです(教えてください-テストしていません)

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function(s,c,a)
    {
        return function()
        {
            onStatusChanged(s,c,a);
        }
    }(select, callid, anotherid);
    td.appendChild(select);
}
于 2008-12-04T19:30:47.397 に答える