HTML表格单元格事件侦听器似乎不起作用?

时间:2017-08-28 14:41:23

标签: javascript dom-events

我正在开发一个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;
    }

1 个答案:

答案 0 :(得分:0)

OP解决方案。

对这个问题发表评论的Chris G在注意到网格“从未附加到文档中”时是绝对正确的。问题是minedGrid函数底部有return grid;,而它应该return newGrid;。如果您想查看此代码的修订版,请refer to this link

我想再次特别强调Chris G的帮助,以及他的minedGrid代码版本:Chris G's JSBin