2017-12-03 7 views
1

私がここで間違っていることを驚かす - 関数はテーブル内のすべてのセルを見て、デフォルトの背景色、フォント色、境界線の色を追加してイベントを追加するどのキーがonmousedownで押されているかによって、セルのフォーマットを変更するanonymouse関数を実行するそれぞれのリスナー。それはすべての細胞の初期のスタイリングを正しく行いますが、それだけです。匿名関数がkeydownイベントで動作しない

function setupPuzzle() { 
    allCells = document.querySelectorAll("table#hitoriGrid td"); 
    for (var i = 0; i < allCells.length; i++) { 
    allCells[i].style.backgroundColor = "rgb(255,255,255)"; 
    allCells[i].style.color = "rgb(0,0,0)"; 
    allCells[i].style.borderRadius = "0px"; 
    allCells[i].addEventListener("onmousedown", function(e) { 
     e.preventDefault(); 
     if (e.shiftKey) { 
     allCells[i].style.backgroundColor = "rgb(255,255,255)"; 
     allCells[i].style.color = "rgb(0,0,0)"; 
     allCells[i].style.borderRadius = "0px"; 
     } else if (e.altKey) { 
     allCells[i].style.backgroundColor = "rgb(0,0,0)"; 
     allCells[i].style.color = "rgb(255,255,255)"; 
     allCells[i].style.borderRadius = "0px"; 
     } else { 
     allCells[i].style.backgroundColor = "rgb(101,101,101)"; 
     allCells[i].style.color = "rgb(255,255,255)"; 
     allCells[i].style.borderRadius = "50%"; 
     } 
    }); 
    } 
} 

答えて

0
    iは、ブロックレベルでスコープされ(したがって、すべてのイベントハンドラのが iの独自の参照を持つことになります)ことを確認してください
  1. 使用mousedownの代わりに、あなたの匿名関数は、ループ(ユーザーがそれをクリックすると)、その後i値はiの最後の値になります後に呼び出さのでonmousedown
  2. allCells[i]の代わりにthisを使用する必要があります。

function setupPuzzle() { 
 
allCells = document.querySelectorAll("table#hitoriGrid td"); 
 
for (var i = 0; i < allCells.length; i++) { 
 
    
 
    allCells[i].style.backgroundColor = "rgb(255,255,255)"; 
 
    allCells[i].style.color = "rgb(0,0,0)"; 
 
    allCells[i].style.borderRadius = "0px"; 
 

 
    
 
    allCells[i].addEventListener("mousedown", function(e) { 
 
    
 
    e.preventDefault();   
 
    if (e.shiftKey) { 
 
     this.style.backgroundColor = "rgb(255,255,255)"; 
 
     this.style.color = "rgb(0,0,0)"; 
 
     this.style.borderRadius = "0px"; 
 
    } 
 
    else if (e.altKey) { 
 
     this.style.backgroundColor = "rgb(0,0,0)"; 
 
     this.style.color = "rgb(255,255,255)"; 
 
     this.style.borderRadius = "0px"; 
 
    } 
 
    else { 
 
     this.style.backgroundColor = "rgb(101,101,101)"; 
 
     this.style.color = "rgb(255,255,255)"; 
 
     this.style.borderRadius = "50%"; 
 
    } 
 
    }); 
 
} 
 
} 
 

 
setupPuzzle();
<table id="hitoriGrid" border="2"> 
 
    <tr> 
 
    <td>Test</td> 
 
    <td>Test</td> 
 
    </tr> 
 
</table>

+1

大きな助け!それははるかに理にかなっています。 – Caelisto

0

短い答えは、あなたのコールバック関数に渡されたイベントがれるonmousedownイベントですのでe.altKeyとe.shiftKeyは常にfalseですので、あなたがれるonmousedownイベントをリッスンしていることです。私は、キーがすでに押された場合、あなたが実際に読むことができるかどうかわからないのですが、私の心に来て解決策の一つは、同様のKeyDownとストア何かのイベントをリッスンすることです:

var keyPressed = []; 
window.onkeyup = function(e) {keys[e.keyCode]=false;} 
window.onkeydown = function(e) {keys[e.keyCode]=true;} 

その後のことができますマウスダウンイベントにキーを押すと配列をチェックインします。

0

編集:他の回答で指摘したようにイベント名の使用mousedownの代わりonmousedown。この編集は、以下のコードで作られています


問題がiはあなたにそれを期待値を指していないということです。 iの範囲は、従ってあなたonmousedownコールバックのすべてはforループの反復ごとに1ずつインクリメントされるallCells.length + 1

iに等しいiを参照しようとしている、それに含まれるブロックに限定されませんこのiの値はすべてのonmousedownハンドラで共有されるので、for-loopの実行が完了するまで、ハンドラはすべてiを参照します。これは最後の値であるallCells.length + 1になります。iはfor-loop終了します。

あなたはES6を使用している場合、あなたはあなたのforループでlet代わりのvarは、問題を解決するために使用することができます:あなたはES6を使用していない場合

function setupPuzzle() { 

    allCells = document.querySelectorAll("table#hitoriGrid td"); 

    for (let i = 0; i < allCells.length; i++) { // uset let instead of var 

    allCells[i].style.backgroundColor = "rgb(255,255,255)"; 
    allCells[i].style.color = "rgb(0,0,0)"; 
    allCells[i].style.borderRadius = "0px"; 
    allCells[i].addEventListener("mousedown", function(e) { 
     e.preventDefault(); 
     if (e.shiftKey) { 
     allCells[i].style.backgroundColor = "rgb(255,255,255)"; 
     allCells[i].style.color = "rgb(0,0,0)"; 
     allCells[i].style.borderRadius = "0px"; 
     } else if (e.altKey) { 
     allCells[i].style.backgroundColor = "rgb(0,0,0)"; 
     allCells[i].style.color = "rgb(255,255,255)"; 
     allCells[i].style.borderRadius = "0px"; 
     } else { 
     allCells[i].style.backgroundColor = "rgb(101,101,101)"; 
     allCells[i].style.color = "rgb(255,255,255)"; 
     allCells[i].style.borderRadius = "50%"; 
     } 
    }); 
    } 
} 

は、あなたが作るために閉鎖を使用することができます

function setupPuzzle() { 

    allCells = document.querySelectorAll("table#hitoriGrid td"); 

    for (var i = 0; i < allCells.length; i++) { 

    (function(i) { // closure 

     allCells[i].style.backgroundColor = "rgb(255,255,255)"; 
     allCells[i].style.color = "rgb(0,0,0)"; 
     allCells[i].style.borderRadius = "0px"; 
     allCells[i].addEventListener("mousedown", function(e) { 
      e.preventDefault(); 
      if (e.shiftKey) { 
      allCells[i].style.backgroundColor = "rgb(255,255,255)"; 
      allCells[i].style.color = "rgb(0,0,0)"; 
      allCells[i].style.borderRadius = "0px"; 
      } else if (e.altKey) { 
      allCells[i].style.backgroundColor = "rgb(0,0,0)"; 
      allCells[i].style.color = "rgb(255,255,255)"; 
      allCells[i].style.borderRadius = "0px"; 
      } else { 
      allCells[i].style.backgroundColor = "rgb(101,101,101)"; 
      allCells[i].style.color = "rgb(255,255,255)"; 
      allCells[i].style.borderRadius = "50%"; 
      } 
     }); 

    })(i); // captures surrounding value of i 

    } 
}