Estoy tratando de agregar un oyente onclick a mis clases. He agregado métodos alert() dentro pero parece que onclick nunca se ejecuta. También he tratado de usar oyentes de eventos, lo que me dio el mismo problema.

Mi código está debajo, ¿cómo puedo recorrer mis clases y agregar un detector de eventos?

/* 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>
0
Jaquarh 9 may. 2019 a las 14:57

3 respuestas

La mejor respuesta

Tienes algunos errores en tu código. por ej. en este bucle for for (el in getByClass("hiding")), el solo le dará el valor clave, no el elemento completo.

Necesita obtener el elemento como este getByClass("hiding")[el].onclick = function() {

He agregado un código. Prueba esto

/* 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>
3
Syed mohamed aladeen 9 may. 2019 a las 12:07

Sé que esto no es CodeReview pero intenté mejorar su código y solucionar el problema.

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

Esto convierte el objeto tipo matriz de todos los elementos secundarios devueltos por { {X0}} en una matriz real e itera a través de cada elemento. También debe usar el en lugar de this aquí porque no hay this definido en ese ámbito.

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>
1
leonheess 9 may. 2019 a las 12:21

getElementsByClassName devuelve la matriz NodeList . y for...in se usa para iterar sobre las propiedades de los objetos. así que use el bucle básico for para iterar sobre la matriz aquí.

Pruebe la siguiente solución.

/* 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>
0
Shiv Kumar Baghel 9 may. 2019 a las 12:20