在JQuery中迭代数组中的新事件监听器

Iterating New Event Listeners in Array in JQuery

本文关键字:事件 监听器 JQuery 迭代 数组 新事件      更新时间:2023-09-26

我正在javascript中创建一个像2046这样的2d游戏。

当用户单击一个块时,该块将变成白色,附近的块也是如此。例如点击[3,4]然后[3 3],[3,4],[3,5],(2、4)(4,4)变成白色。

但是,如果附近的块具有比被单击的块更大的索引,则事件处理程序无法进行这些更改。即[3,5],[4,4]出现故障。

我尝试用闭包包装处理程序,但仍然失败。什么情况下会出现这种情况?

注:问题发生在WAITING_USER_SELECT_BLOCK的情况下。setBlock(x,y)函数返回null,而它应该是blocks[y][x]

$(document).ready(function() {
    Game.init();
});
var Game = (function() {
    var xNumber = 5;
    var yNumber = 5;
    var blocks = [];
    function setBlock(x, y) {
        if (blocks[y])
            if (blocks[y][x]) {
                console.log(blocks[y][x]);
                blocks[y][x].css("background", "#FFF");
            }
    };
    function changeStatus(status) {
        switch (status) {
            case "WAITING_LOGIC_NEW_GAME":
                $('#plate').width(50 * xNumber);
                $('#plate').height(50 * yNumber);
                for (let y = 0; y < yNumber; y++) {
                    for (let x = 0; x < xNumber; x++) {
                        if (blocks[y] == null) blocks[y] = [];
                        blocks[y][x] = $(['<div class="plate-block" ',
                                'data-block-at-x="' + x + '" ',
                                'data-block-at-y="' + y + '"></div>'
                            ]
                            .join(''));
                        $('#plate').append(blocks[y][x]);
                    }
                }
                break;
            case "WAITING_USER_SELECT_BLOCK":
                $('.plate-block').click(function() {
                    var block = $(this);
                    var sx = block.attr('data-block-at-x');
                    var sy = block.attr('data-block-at-y');
                    setBlock(sx, sy);
                    setBlock(sx, sy - 1);
                    setBlock(sx, sy + 1);
                    setBlock(sx - 1, sy);
                    setBlock(sx + 1, sy);
                    console.log("current block");
                    console.log(block);
                });
                break;
        }
    }
    return {
        init: function() {
            changeStatus("WAITING_LOGIC_NEW_GAME");
            changeStatus("WAITING_USER_SELECT_BLOCK");
        }
    }
})();
#plate {
    width: 350px;
    height: 350px;
    background: #EFEFEF;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-user-select: none;
    -khtml-user-select: none; 
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.plate-block {
    width: 50px;
    height: 50px;
    background:#EEE;
    border: 1px solid #DDD;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    display:inline-block;
    overflow: hidden;
    line-height: 50px;
    text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="plate"></div>

从DOM读取时,value被读取为字符串而不是数字。同时,+运算符作为字符串的连接运算符。

解析为number。

var sx = +block.attr('data-block-at-x');

示例

$(document).ready(function() {
  Game.init();
});
var Game = (function() {
  var xNumber = 5;
  var yNumber = 5;
  var blocks = [];
  function setBlock(x, y) {
    if (blocks[y])
      if (blocks[y][x]) {
        console.log(blocks[y][x]);
        blocks[y][x].css("background", "#FFF");
      }
  };
  function changeStatus(status) {
    switch (status) {
      case "WAITING_LOGIC_NEW_GAME":
        $('#plate').width(50 * xNumber);
        $('#plate').height(50 * yNumber);
        for (let y = 0; y < yNumber; y++) {
          for (let x = 0; x < xNumber; x++) {
            if (blocks[y] == null) blocks[y] = [];
            blocks[y][x] = $(['<div class="plate-block" ',
                'data-block-at-x="' + x + '" ',
                'data-block-at-y="' + y + '"></div>'
              ]
              .join(''));
            $('#plate').append(blocks[y][x]);
          }
        }
        break;
      case "WAITING_USER_SELECT_BLOCK":
        $('.plate-block').click(function() {
          var block = $(this);
          var sx = +block.attr('data-block-at-x');
          var sy = +block.attr('data-block-at-y');
          setBlock(sx, sy);
          setBlock(sx, sy - 1);
          setBlock(sx, sy + 1);
          setBlock(sx - 1, sy);
          setBlock(sx + 1, sy);
          console.log("current block");
          console.log(block);
        });
        break;
    }
  }
  return {
    init: function() {
      changeStatus("WAITING_LOGIC_NEW_GAME");
      changeStatus("WAITING_USER_SELECT_BLOCK");
    }
  }
})();
#plate {
  width: 350px;
  height: 350px;
  background: #EFEFEF;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.plate-block {
  width: 50px;
  height: 50px;
  background: #EEE;
  border: 1px solid #DDD;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  display: inline-block;
  overflow: hidden;
  line-height: 50px;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="plate"></div>