我正在开发一个HTML / Javascript项目来创建一个简单的Minesweeper游戏。为了创建可单击的单元格网格,我采用了in another thread找到的代码。该代码可以完全独立运行(有关详细信息,请参阅this JSBin):
var lastClicked;
var grid = clickableGrid(10,10,onClick);
document.body.appendChild(grid);
// This is the clickableGrid object constructor. It takes in the number of rows and columns
// for the grid, and a callback function that will be executed when a cell is clicked
function clickableGrid( rows, cols, callback ){
// 'i' is the variable that will store the number in each cell. A 10x10
// grid, for example, will see i range from 1 (top left cell) to 100 (bottom right cell)
var i=0;
// Create the table element and assign it a class name so that CSS formatting
// may be applied
var grid = document.createElement('table');
grid.className = 'grid';
// Build the grid row by row
for (var r=0;r<rows;++r){
// Create a table row element and append it to the table element ('grid')
var tr = grid.appendChild(document.createElement('tr'));
tr.row = r;
// Build the row cell by cell
for (var c=0;c<cols;++c){
// Create the cell element and append it to the row element ('tr')
var cell = tr.appendChild(document.createElement('td'));
// Input the number to the cell's innerHTML
cell.innerHTML = ++i;
// Add an event listener that will execute the callback function
// when the cell is clicked, using the cell's element and information
cell.addEventListener('click',(function(el, r, c, i){
return function() {
callback(el, r, c, i);
}
})(cell, r, c, i),false);
}
}
return grid;
}
// This function contains the actions we want to be executed when the click occurs
function onClick(el, row, col, i) {
// Log to the console the details of the cell that was clicked
console.log("You clicked on element:",el);
console.log("You clicked on row:",row);
console.log("You clicked on col:",col);
console.log("You clicked on item #:",i);
// Record in the element that it was clicked
el.className='clicked';
// If the element is not the same as
if (lastClicked) lastClicked.className='';
lastClicked = el;
}
然而,我似乎无法在我的扫雷游戏中使其正常工作。 “挖掘”网格构建并附加到DOM,但不应用innerHTML和侦听器。 This other JSBin包含我目前所拥有的所有游戏代码。目前的流程是:
1)运行init以初始化页面并创建所有元素。部分内容包括向“新游戏”按钮添加事件监听器。
2)单击“新游戏”按钮时,创建一个将被“挖掘”的可点击网格。目前,没有地雷被放置,但代码试图在每个单元格内放置一个“X”。此外,每个单元格都应该附加一个事件监听器。
游戏中的相关代码部分是:
function startGame() {
var gameDifficulty = document.getElementsByTagName("select")[0].value;
var currGrid = document.querySelector('.grid');
var newGrid = new minedGrid(gameDifficulty, onClick);
currGrid.parentNode.replaceChild(newGrid, currGrid);
}
// minedGrid object constructor: creates and returns a fully-mined and
// prepared Minesweeper grid
function minedGrid(difficulty, callback){
var rows, cols, mines;
var newGrid = document.createElement('table');
newGrid.className = 'grid';
switch (difficulty) {
case 0:
rows = 10;
cols = 10;
mines = 10;
break;
case 1:
rows = 16;
cols = 16;
mines = 40;
break;
case 2:
rows = 16;
cols = 30;
mines = 99;
break;
default:
rows = 10;
cols = 10;
mines = 10;
break;
}
for (var r = 0; r < rows; ++r) {
var tr = newGrid.appendChild(document.createElement('tr'));
for (var c = 0; c < cols; ++c) {
var cell = tr.appendChild(document.createElement('td'));
cell.innerHTML = "X";
cell.addEventListener('click',(function(el, r, c){
return function() {
callback(el, r, c);
}
})(cell, r, c),false);
}
}
return grid;
}
// This function contains the actions we want to be executed when the click occurs
function onClick(el, row, col) {
// Log to the console the details of the cell that was clicked
console.log("You clicked on element:",el);
console.log("You clicked on row:",row);
console.log("You clicked on col:",col);
// Record in the element that it was clicked
el.className='clicked';
// If the element is not the same as
if (lastClicked) lastClicked.className='';
lastClicked = el;
}
答案 0 :(得分:0)
OP解决方案。
对这个问题发表评论的Chris G在注意到网格“从未附加到文档中”时是绝对正确的。问题是minedGrid函数底部有return grid;
,而它应该return newGrid;
。如果您想查看此代码的修订版,请refer to this link。
我想再次特别强调Chris G的帮助,以及他的minedGrid代码版本:Chris G's JSBin。