2016-05-30 1 views
1

私は問題があります - 私はそれを作成中に動的に生成されたテーブルの各セルに.onClickイベントを追加したいと思います。javascript - テーブルの各セルに.onClickを与える

cell.onclick = function(){     
     mouseClick(row_number,i, cell);        
    }; 

ただし、イベントは各行の最後のセルに追加されたように見えます。どのように可能ですか?以前のものを何とかオーバーライドしていますか?そしてそれを動作させる方法は?

function drawRow(rowData, length, keys, row_number){ 
//rowData - object where the row data is stored, length-row length, keys - object with table keys stored, row_number - number of the row 
    var rowData=rowData; 
    var row = document.createElement("tr");  
    for(i=0; i<length; i++){  
     var cell = document.createElement("td"); 
     console.log("Creating event for "+i+" ."); 
     cell.onclick = function(){     
      mouseClick(row_number,i, cell);        
     }; 
     var key = keys[i];  
     var cell_text = document.createTextNode(rowData[key]);   
     cell.appendChild(cell_text); 
     row.appendChild(cell); 
    } 
    return row; 
} 
+0

はクロージャの恐ろしく不便な世界へようこそ;) –

+0

'私はグローバルなスコープを持っています(これは悪い習慣です)、 'row_number'と' cell'は外部関数にスコープされているので、すべてのセルで同じになります。あなたは[閉鎖でそれを修正することができます](http://stackoverflow.com/q/750486/4642212)、私は**イベント委任**を強くお勧めします。 – Xufox

+0

この質問はこれの複製ですhttp://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue javascriptの悪名高いループクロージャの問題の可能な解決策と説明については、そこに答えを見てください。 – juan8a

答えて

1

JavaScript-landでよく見られる問題の1つです。

forループが完了したの後に、あなたのonclick関数はまで呼び出されません。 forループが完了すると、iの値はlengthの値になります。それだけでそれを読もうとします。言い換えれば、あなたのコールバックのひとつひとつの1はあなたが最後にコールバックを実行する時点で

function() {mouseClick(row_number, i, cell} 

を言う、iの値はその最後の値です。

あなたはES6を使用している場合は、代わりに

for (let i=0; i<length; i++) 

letはブロックその自身変数iの各呼び出しを与える書き込み。あなたのコードでは、すべてのセルの間で1つだけiが共有されています。それはすべての細胞が同じことをしているように見える理由です!あなたはES5ゲームに残っている場合

は、

cell.onclick = (function (j) { 
     return function() { 
      mouseClick(row_number, j, cell); 
     }        
    })(i); 

これは、ループの各ポイントで、あなたのコールバック関数のそれぞれにiのコピーを与えて、あなたのコードの内側部分を交換してください。最初のループ、iは0の値を持っており、あなたが得るコールバックが

function() {mouseClick(row_number, 0, cell} 

あるループの2回目の反復が

function() {mouseClick(row_number, 1, cell} 

などを生産!

かなりクールですが、letとES6のやり方は、ちょっとうまくやっています。

(。。また、アレイ上forEach方法でこのことを行う方法があるこれらも、ループの反復が、インデックス変数を共有していないことを確認)

+0

素敵な答えRay - mindはES5ソリューションも追加していますか?ES6はまだ完全にはサポートされておらず、OPがES6を使用していない可能性があります。 –

+0

ありがとう、良いアイデア。 –

+0

ありがとうございます! –

関連する問題