HTML/JavaScript Tic Tac Toe with a 2D array



我是HTML5和JavaScript的新手,我正在努力学习游戏编程。所以我决定尝试制作一款用2D数组渲染棋盘的井字游戏。我设置了它,所以它改变颜色与CSS:hover,但现在我只是试图使每个框改变为红色,当它被点击,这是我卡住的地方。

我不是在找任何人来完成我的代码,只是我想把事情慢慢来(有点),我想自己弄清楚。我的问题是我如何使每个框改变颜色,当你点击?目前我有数组的每个元素创建一个,然后我定位他们,并添加一个addEventListener到他们的类。我的代码的工作原理是,当你点击最后一个元素时,它会改变颜色,但其他元素都不会。

这是我的代码。

<!doctype html>
<title>Tic Tac Toe</title>
<style>
#stage
{
    position: relative;
}
.cell
{
    position: absolute;
    width: 100px;
    height: 100px;
    border: 1px solid black;
    background-color: white;
}
.cell:hover
{
    background-color: blue;
}
</style>
<div id="stage"></div>
<script>
//get a reference to the stage
var stage = document.querySelector("#stage");
//the 2d array that defines the board
var board = 
[
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
];
//the size of each cell
var SIZE = 100;
//the space between each cell
var SPACE = 10;
//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;
for(var row = 0; row < ROWS; row++)
{
    for(var column = 0; column < COLUMNS; column++)
    {
        //create a div HTML element called cell
        var cell = document.createElement("div");
        //set its CSS class to cell
        cell.setAttribute("class", "cell");
        //add the div HTML element to the stage
        stage.appendChild(cell);
        //position the cell
        cell.style.top = row * (SIZE + SPACE) + "px";
        cell.style.left = column * (SIZE + SPACE) + "px";
    }
}
cell.addEventListener("click", clickHandler, false);
function clickHandler()
{
    cell.style.backgroundColor = "red";
    console.log("worked");
}
</script>

任何帮助都将非常感激!谢谢!

有一个简单的错误,您将click处理程序绑定在循环之外。当你将它移动到循环中时,你需要将cell.style更改为this.style,因为cell将引用循环后变量的最后一个值,而不是当前单元格。

还值得注意的是,由于addEventListener方法,您当前的代码与Internet Explorer 8及以下版本不兼容。如果您计划在页面上操作元素,建议使用jQuery,这在某种程度上使这些兼容性问题无关紧要(在这种情况下,您将需要v1.x。jquery的X版本,从v2.x开始。x已放弃对ie8的支持

var stage = document.querySelector("#stage");
//the 2d array that defines the board
var board = [
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
];
//the size of each cell
var SIZE = 100;
//the space between each cell
var SPACE = 10;
//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;
for(var row = 0; row < ROWS; row++){
    for(var column = 0; column < COLUMNS; column++){
        //create a div HTML element called cell
        var cell = document.createElement("div");
        //set its CSS class to cell
        cell.setAttribute("class", "cell");
        //add the div HTML element to the stage
        stage.appendChild(cell);
        //position the cell
        cell.style.top = row * (SIZE + SPACE) + "px";
        cell.style.left = column * (SIZE + SPACE) + "px";
        //handle click
        cell.addEventListener("click", clickHandler, false);
    }
}
function clickHandler(){
    this.style.backgroundColor = "red";
    console.log("worked");
}

解决方法很简单:

  • 首先为每个元素注册事件(这样它就在循环中)
  • 在事件函数中使用参数event

我得到了这个:

//get a reference to the stage
var stage = document.querySelector("#stage");
//the 2d array that defines the board
var board = 
[
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]
];
//the size of each cell
var SIZE = 100;
//the space between each cell
var SPACE = 10;
//display the array
var ROWS = board.length;
var COLUMNS = board[0].length;
for(var row = 0; row < ROWS; row++)
{
    for(var column = 0; column < COLUMNS; column++)
    {
        //create a div HTML element called cell
        var cell = document.createElement("div");
        //set its CSS class to cell
        cell.setAttribute("class", "cell");
        //add the div HTML element to the stage
        stage.appendChild(cell);
        //position the cell
        cell.style.top = row * (SIZE + SPACE) + "px";
        cell.style.left = column * (SIZE + SPACE) + "px";
        cell.addEventListener("click", clickHandler, false);
    }
}

function clickHandler(event)
{
    console.log(event);
    event.currentTarget.style.backgroundColor = "red";
    console.log("worked");
}
下面是我的测试:http://jsfiddle.net/DSNLR/

我对JavaScript一无所知,但对Java略知一二。我认为

cell.addEventListener("click", clickHandler, false);

必须像这样放在for循环中:

for(var row = 0; row < ROWS; row++)
{
  for(var column = 0; column < COLUMNS; column++)
  {
    //create a div HTML element called cell
    var cell = document.createElement("div");
    //do your stuff here
    //now the event listener
    cell.addEventListener("click", clickHandler, false);
  }
}

应该可以。您只将它添加到最后一个单元格。

最简单的方法:1. 把

cell.addEventListener("click", clickHandler, false);

放入循环中,因为每个单元格都应该有自己的侦听器。2. 处理程序应该与适当的cell一起工作,而不是与一些通用的cell

一起工作。
function clickHandler()
{
    this.style.backgroundColor = "red";
    console.log("worked");
}

如果您想提高性能,那么您应该监听父元素(包含所有单元格)并调度事件。

相关内容

  • 没有找到相关文章

最新更新