单击元素时,不会调用click的事件侦听器

时间:2019-05-09 11:57:54

标签: javascript html

我正在尝试向我的班级添加onclick侦听器。我在内部添加了alert()方法,但是似乎从未执行过onclick。我也尝试过使用事件监听器,这给了我同样的问题。

我的代码在下面,如何遍历我的类并追加事件侦听器?

/* Easier function to use than rewriting document.get... */
function getById(id) {
    return document.getElementById(id)
}

function getByClass(c) {
    return document.getElementsByClassName(c)
}

/* Random number calculation */
function random(xOrY) {
    return Math.floor(Math.random() * (+xOrY - +1)) + 1
}

/* Create a grid */
function createGrid(isHiding) {
    var grid = document.createElement("div")
    grid.className = isHiding ? "hiding" : "grid"
    return grid
}

/* Set configurations we will use */
var settings = {
    hiding: 4,
    x: 6,
    y: 6,
    maxAttempts: 6 * 6,
    container: 'grid-container'
}

/* Set up the game */
var game = {
    settings: settings,
    attempts: 0,
    numberFound: 0,
    hidingGrids: []
}

/* Generate the hiding grids */
for (i = 1; i <= game.settings.hiding; i++) {
    game.hidingGrids.push({
        x: random(game.settings.x),
        y: random(game.settings.y)
    })
}

/* Generate the grids */
for (y = 1; y <= game.settings.y; y++) {
    for (x = 1; x <= game.settings.x; x++) {
        var gridHasHid = false
        game.hidingGrids.forEach(function(grid) {
            if (y == grid.y && x == grid.x) {
                gridHasHid = true
                /* Create a hidden grid */
                getById(game.settings.container).appendChild(createGrid(true))
            }
        })
        if (!gridHasHid) {
            /**
             *If it gets here, the grid wasn't a hidden grid
             * thus we need to add a standard grid.
             */
            getById(game.settings.container).appendChild(createGrid(false))
        }
    }
    /* Append a break line to start the next row */
    var br = document.createElement("br")
    getById(game.settings.container).appendChild(br)
}

/* Lets set listen handlers on the incorrect and correct grids */
for (el in getByClass("grid")) {
    el.onclick = function() {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts == game.settings.maxAttempts || game.numberFound == game.settings.hiding) {
            alert("The game is already over.")
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (this.style.background == "red") return
        /* If it got here, all checks passed. Lets update the colour and send an message */
        this.style.background = "red"
        alert("Incorrect, you have " + ++game.attempts + " attempts left.")
    }
}

for (el in getByClass("hiding")) {
    el.onclick = function() {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts == game.settings.maxAttempts || game.numberFound == game.settings.hiding) {
            alert("The game is already over.")
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (this.style.background == "blue") return
        /* If it got here, all checks passed. Lets update the colour and send an message */
        this.style.background = "blue"
        alert("Correct, you have " + ++game.attempts + " attempts left.")
    }
}
#grid-container {
  display: inline-block;
  width: 100%;
}

.grid {
  display: inline-block;
  background-color: #000;
  padding: 5%;
  margin: 2%;
}

.hiding {
  background-color: #000;
  display: inline-block;
  padding: 5%;
  margin: 2%;
}

/* Uncomment below to see where they're hiding (DEBUG) */

.hiding {
  background-color: blue;
}
<div id="grid-container"></div>

3 个答案:

答案 0 :(得分:3)

您的代码中有一些错误。例如在此for循环for (el in getByClass("hiding"))中,el仅给您键值,而不是整个元素。

您需要获取类似getByClass("hiding")[el].onclick = function() {的元素

我添加了一些代码。试试这个

/* Easier function to use than rewriting document.get... */
function getById(id) {
    return document.getElementById(id)
}

function getByClass(c) {
    return document.getElementsByClassName(c)
}

/* Random number calculation */
function random(xOrY) {
    return Math.floor(Math.random() * (+xOrY - +1)) + 1
}

/* Create a grid */
function createGrid(isHiding) {
    var grid = document.createElement("div")
    grid.className = isHiding ? "hiding" : "grid"
    return grid
}

/* Set configurations we will use */
var settings = {
    hiding: 4,
    x: 6,
    y: 6,
    maxAttempts: 6 * 6,
    container: 'grid-container'
}

/* Set up the game */
var game = {
    settings: settings,
    attempts: 0,
    numberFound: 0,
    hidingGrids: []
}

/* Generate the hiding grids */
for (i = 1; i <= game.settings.hiding; i++) {
    game.hidingGrids.push({
        x: random(game.settings.x),
        y: random(game.settings.y)
    })
}

/* Generate the grids */
for (y = 1; y <= game.settings.y; y++) {
    for (x = 1; x <= game.settings.x; x++) {
        var gridHasHid = false
        game.hidingGrids.forEach(function(grid) {
            if (y == grid.y && x == grid.x) {
                gridHasHid = true
                /* Create a hidden grid */
                getById(game.settings.container).appendChild(createGrid(true))
            }
        })
        if (!gridHasHid) {
            /**
             *If it gets here, the grid wasn't a hidden grid
             * thus we need to add a standard grid.
             */
            getById(game.settings.container).appendChild(createGrid(false))
        }
    }
    /* Append a break line to start the next row */
    var br = document.createElement("br")
    getById(game.settings.container).appendChild(br)
}

/* Lets set listen handlers on the incorrect and correct grids */
for (el in getByClass("grid")) {
    getByClass("grid")[el].onclick = function() {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts == game.settings.maxAttempts || game.numberFound == game.settings.hiding) {
            alert("The game is already over.")
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (this.style.background == "red") return
        /* If it got here, all checks passed. Lets update the colour and send an message */
        this.style.background = "red"
        alert("Incorrect, you have " + ++game.attempts + " attempts left.")
    }
}

for (el in getByClass("hiding")) {
    getByClass("hiding")[el].onclick = function() {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts == game.settings.maxAttempts || game.numberFound == game.settings.hiding) {
            alert("The game is already over.")
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (this.style.background == "blue") return
        /* If it got here, all checks passed. Lets update the colour and send an message */
        this.style.background = "blue"
        alert("Correct, you have " + ++game.attempts + " attempts left.")
    }
}
#grid-container {
  display: inline-block;
  width: 100%;
}

.grid {
  display: inline-block;
  background-color: #000;
  padding: 5%;
  margin: 2%;
}

.hiding {
  background-color: #000;
  display: inline-block;
  padding: 5%;
  margin: 2%;
}

/* Uncomment below to see where they're hiding (DEBUG) */

.hiding {
  background-color: blue;
}
<div id="grid-container"></div>

答案 1 :(得分:1)

我知道这不是CodeReview,但我试图改善您的代码并解决此问题。

Array.from(getByClass("grid")).forEach(el => {
    el.addEventListener('click', () => {
        // your code
    });
});

这会将Document​.get​Elements​ByClass​Name()返回的所有子元素的类似于数组的对象转换为实际数组,并遍历每个元素。您还必须在这里使用el而不是this,因为在该范围中没有定义this

function getById(id) {
    return document.getElementById(id)
}

function getByClass(c) {
    return document.getElementsByClassName(c)
}

/* Random number calculation */
function random(xOrY) {
    return Math.floor(Math.random() * (+xOrY - +1)) + 1
}

/* Create a grid */
function createGrid(isHiding) {
    let grid = document.createElement("div");
    grid.className = isHiding ? "hiding" : "grid";
    return grid
}

/* Set configurations we will use */
let settings = {
    hiding: 4,
    x: 6,
    y: 6,
    maxAttempts: 6 * 6,
    container: 'grid-container'
};

/* Set up the game */
let game = {
    settings: settings,
    attempts: 0,
    numberFound: 0,
    hidingGrids: []
};

/* Generate the hiding grids */
for (let i = 1; i <= game.settings.hiding; i++) {
    game.hidingGrids.push({
        x: random(game.settings.x),
        y: random(game.settings.y)
    })
}

/* Generate the grids */
for (let y = 1; y <= game.settings.y; y++) {
    for (let x = 1; x <= game.settings.x; x++) {
        let gridHasHid = false;
        game.hidingGrids.forEach(function(grid) {
            if (y === grid.y && x === grid.x) {
                gridHasHid = true;
                /* Create a hidden grid */
                getById(game.settings.container).appendChild(createGrid(true))
            }
        });
        if (!gridHasHid) {
            /**
             *If it gets here, the grid wasn't a hidden grid
             * thus we need to add a standard grid.
             */
            getById(game.settings.container).appendChild(createGrid(false))
        }
    }
    /* Append a break line to start the next row */
    let br = document.createElement("br")
    getById(game.settings.container).appendChild(br)
}

/* Lets set listen handlers on the incorrect and correct grids */
Array.from(getByClass("grid")).forEach(el => {
    el.addEventListener('click', () => {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts === game.settings.maxAttempts || game.numberFound === game.settings.hiding) {
            alert("The game is already over.");
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (el.style.background === "red") return;
        /* If it got here, all checks passed. Lets update the colour and send an message */
        el.style.background = "red";
        alert(`Incorrect, you have ${++game.attempts} attempts left.`)
    });
});

Array.from(getByClass("hiding")).forEach(el => {
    el.addEventListener('click', () => {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts === game.settings.maxAttempts || game.numberFound === game.settings.hiding) {
            alert("The game is already over.");
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (el.style.background === "blue") return;
        /* If it got here, all checks passed. Lets update the colour and send an message */
        el.style.background = "blue";
        alert(`Correct, you have ${++game.attempts} attempts left.`)
    });
});
#grid-container {
  display: inline-block;
  width: 100%;
}

.grid {
  display: inline-block;
  background-color: #000;
  padding: 5%;
  margin: 2%;
}

.hiding {
  background-color: #000;
  display: inline-block;
  padding: 5%;
  margin: 2%;
}

/* Uncomment below to see where they're hiding (DEBUG) */

.hiding {
  background-color: blue;
}
<div id="grid-container"></div>

答案 2 :(得分:0)

getElementsByClassName返回 NodeList 数组。 for...in用于迭代对象的属性。因此,请使用基本的for循环在此处遍历数组。

尝试以下解决方案。

/* Easier function to use than rewriting document.get... */
function getById(id) {
    return document.getElementById(id)
}

function getByClass(c) {
    return document.getElementsByClassName(c)
}

/* Random number calculation */
function random(xOrY) {
    return Math.floor(Math.random() * (+xOrY - +1)) + 1
}

/* Create a grid */
function createGrid(isHiding) {
    var grid = document.createElement("div")
    grid.className = isHiding ? "hiding" : "grid"
    return grid
}

/* Set configurations we will use */
var settings = {
    hiding: 4,
    x: 6,
    y: 6,
    maxAttempts: 6 * 6,
    container: 'grid-container'
}

/* Set up the game */
var game = {
    settings: settings,
    attempts: 0,
    numberFound: 0,
    hidingGrids: []
}

/* Generate the hiding grids */
for (i = 1; i <= game.settings.hiding; i++) {
    game.hidingGrids.push({
        x: random(game.settings.x),
        y: random(game.settings.y)
    })
}

/* Generate the grids */
for (y = 1; y <= game.settings.y; y++) {
    for (x = 1; x <= game.settings.x; x++) {
        var gridHasHid = false
        game.hidingGrids.forEach(function(grid) {
            if (y == grid.y && x == grid.x) {
                gridHasHid = true
                /* Create a hidden grid */
                getById(game.settings.container).appendChild(createGrid(true))
            }
        })
        if (!gridHasHid) {
            /**
             *If it gets here, the grid wasn't a hidden grid
             * thus we need to add a standard grid.
             */
            getById(game.settings.container).appendChild(createGrid(false))
        }
    }
    /* Append a break line to start the next row */
    var br = document.createElement("br")
    getById(game.settings.container).appendChild(br)
}

/* Lets set listen handlers on the incorrect and correct grids */
for (el in getByClass("grid")) {
    el.onclick = function() {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts == game.settings.maxAttempts || game.numberFound == game.settings.hiding) {
            alert("The game is already over.")
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (this.style.background == "red") return
        /* If it got here, all checks passed. Lets update the colour and send an message */
        this.style.background = "red"
        alert("Incorrect, you have " + ++game.attempts + " attempts left.")
    }
}

var hidingClass = getByClass("hiding");
for(var i = 0; i < hidingClass.length; i++){
   var el = hidingClass[i];

    el.onclick = function() {
        /* We need to go through all our checks to ensure the game hasn't ended */
        if (game.attempts == game.settings.maxAttempts || game.numberFound == game.settings.hiding) {
            alert("The game is already over.")
            return
        }
        /* Check that the tile hasn't already been clicked using our colour factor */
        if (this.style.background == "blue") return
        /* If it got here, all checks passed. Lets update the colour and send an message */
        this.style.background = "blue"
        alert("Correct, you have " + ++game.attempts + " attempts left.")
    }
}
#grid-container {
  display: inline-block;
  width: 100%;
}

.grid {
  display: inline-block;
  background-color: #000;
  padding: 5%;
  margin: 2%;
}

.hiding {
  background-color: #000;
  display: inline-block;
  padding: 5%;
  margin: 2%;
}

/* Uncomment below to see where they're hiding (DEBUG) */

.hiding {
  background-color: blue;
}
<div id="grid-container"></div>