Reputation: 6693
I am trying to add an onclick
listener to my classes. I have added alert()
methods inside but it seems that the onclick
is never executed. I have tried to use event listeners too which gave me the same issue.
My code is below, how can I loop through my classes and append an event listener?
/* 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>
Upvotes: 0
Views: 56
Reputation: 21411
I know this isn't CodeReview but I tried to improve your code and fix the issue.
Array.from(getByClass("grid")).forEach(el => {
el.addEventListener('click', () => {
// your code
});
});
This converts the array-like object of all child elements returned by Document.getElementsByClassName()
into an actual array and iterates through each element. You also have to use to el
instead of this
here because there is no this
defined in that scope.
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>
Upvotes: 1
Reputation: 2480
getElementsByClassName
returns NodeList array. and for...in
is used to iterate over the properties of objects. so use basic for
loop to iterate over array here.
Try below solution.
/* 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>
Upvotes: 0
Reputation: 6755
you have some mistakes in your code. for eg. in this for loop for (el in getByClass("hiding"))
the el
will only give you the key value not the entire element.
you need to get the element like this getByClass("hiding")[el].onclick = function() {
I have added some code. Try this
/* 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>
Upvotes: 3