匿名函数不能与keydown事件一起使用

时间:2017-12-03 19:00:35

标签: javascript

想知道我在这里做错了什么 - 该函数应该查看表中的所有单元格,添加它们的默认背景颜色,字体颜色和边框颜色,然后为执行anonymouse函数的每个单元添加一个Event Listener。更改单元格格式,具体取决于在mousedown上按下哪个键。它正确地完成了所有单元格的初始样式,但这就是它。

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%";
      }
    });
  }
}

3 个答案:

答案 0 :(得分: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;}

然后在鼠标按下事件中,如果按下了键,则可以检入数组。

答案 1 :(得分:0)

修改:使用mousedown代替onmousedown作为其他答案所指出的事件名称。此编辑已在以下代码中进行:

问题是i没有指向您期望的价值。 i的范围不仅限于其中包含的块,因此您的所有onmousedown回调都将引用等于i <的allCells.length + 1 / p> 在for循环的每次迭代中,

i递增1,并且所有i处理程序共享此onmousedown值,因此当你的for循环时完成运行后,您的处理程序将全部引用i,这将是allCells.length + 1,因为这是for循环退出之前的最后一个值i

如果您使用的是ES6,则可以在for循环中使用let代替var来解决问题:

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%";
      }
    });
  }
}

如果您没有使用ES6,可以使用闭包来确保i在块级别作用域(因此所有的事件处理程序都有自己的i)的参考:

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

  }
}

答案 2 :(得分:0)

  1. 使用mousedown代替onmousedown
  2. 因为在循环之后调用了匿名函数(当用户单击它时),i值将是i的最后一个值。 因此,您需要使用this代替allCells[i]
  3. &#13;
    &#13;
    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();
    &#13;
    <table id="hitoriGrid" border="2">
      <tr>
        <td>Test</td>
        <td>Test</td>
      </tr>
    </table>
    &#13;
    &#13;
    &#13;