简体   繁体   English

匿名功能不适用于按键事件

[英]Anonymous Function not working with keydown events

Wondering what I'm doing wrong here - the function is supposed to look at all the cells in a table, add their default background color, font color and border color and then add an Event Listener to each that executes the anonymouse function to change a cells formatting depending on what key is held down onmousedown. 想知道我在做什么错-该功能应该查看表中的所有单元格,添加其默认背景色,字体颜色和边框颜色,然后向每个执行匿名函数的事件监听器添加一个事件侦听器以更改单元格的格式化取决于onmousedown上按下的键。 It does the initial styling of all the cells correctly but that's it. 它正确地对所有单元进行了初始样式设置,仅此而已。

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

Short answer is that you are listening for an onmousedown event so e.altKey and e.shiftKey is always false because the event passed to your callback function is an onmousedown event. 简短的答案是,您正在监听onmousedown事件,因此e.altKey和e.shiftKey始终为false,因为传递给回调函数的事件是onmousedown事件。 I am not sure if you can actually read if a key is already pressed but one of solutions that come to my mind is to listen on events for keydown and store something like: 我不确定您是否可以真正阅读是否已按下某个键,但是我想到的解决方案之一就是监听事件以进行按键按下并存储以下内容:

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

Then on mouse down event you can check in an array if key is pressed. 然后在发生鼠标按下事件时,您可以在阵列中检查是否按下了键。

Edit: use mousedown instead of onmousedown for the event name as pointed out by the other answers. 编辑:使用其他事件所指出的事件名称使用mousedown而不是onmousedown This edit has been made in the below code: 此编辑已通过以下代码进行:


The issue is that i does not point to the value that you expect it to. 问题是i没有指向您期望的值。 The scope of i is not confined to the block that it is contained in, so all of your onmousedown callbacks are going to reference an i that is equal to allCells.length + 1 i的范围不限于它所包含的块,因此所有onmousedown回调都将引用一个等于allCells.length + 1i

i is incremented by 1 on each iteration of the for-loop, and this i value is shared by all of your onmousedown handlers, so by the time your for-loop finishes running, your handlers will all refer to i , which will be allCells.length + 1 as that is the last value i takes before the for-loop exits. 在for循环的每次迭代中, i都会增加1,并且所有onmousedown处理程序都共享i值,因此,在您的for循环运行结束时,处理程序将全部引用i ,即allCells.length + 1因为这是i在for循环退出之前所取的最后一个值。

If you are using ES6, you can use let instead of var in your for-loop to fix the issue: 如果使用的是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%";
      }
    });
  }
}

If you are not using ES6, you can use a closure to make sure that i is scoped at the block-level (and therefore all of your event handlers will have their own reference of i ): 如果您不使用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

  }
}
  1. Use mousedown instead of onmousedown 使用mousedown代替onmousedown
  2. because your anonymous function invoked after the loop (When the user clicked it) then i value will be the last value of i . 因为你的匿名函数循环后调用(当用户点击它),那么i的价值将是最后的价值i so you need to use this instead of allCells[i] . 所以您需要使用this代替allCells[i]

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM