Home > Software design >  How do I identify and compare which cell was clicked on a grid JS?
How do I identify and compare which cell was clicked on a grid JS?

Time:12-31

sorry that the post is a bit long its just to be very clear about what im need. I'm making a Board 8x8. i did it like using loop. works perfect.

// Create a center tag to center all the elements
        var center = document.createElement('center');
        var count = 1;
        // Create a table element
        var ChessTable = document.createElement('table');
        for (var i = 0; i < 8; i  ) {

            // Create a row
            var tr = document.createElement('tr');
            for (var j = 0; j < 8; j  ) {

                // Create a cell
                var td = document.createElement('td');

                // If the sum of cell coordinates is even
                // then color the cell white
                if ((i   j) % 2 == 0) {

                    // Create a class attribute for all white cells
                    td.setAttribute('class', 'cell whitecell');
                    tr.appendChild(td);
                   // td.appendChild(document.createTextNode(`Cell I${i}/J${j}`));
                }

                // If the sum of cell coordinates is odd then
                // color the cell black
                else {

                    // Create a class attribute for all black cells
                    td.setAttribute('class', 'cell blackcell');

                    // Append the cell to its row
                    tr.appendChild(td);
                   // td.appendChild(document.createTextNode(`Cell I${i}/J${j}`));
                    
                }
            }

            // Append the row
            ChessTable.appendChild(tr);
        }
        center.appendChild(ChessTable);

        // Modifying table attribute properties
        ChessTable.setAttribute('cellspacing', '0');
        ChessTable.setAttribute('width', '270px');
        document.body.appendChild(center);
        console.log(ChessTable);

now i needed to make option that if you click on certain cell the cell changing color. works perfect too.

 function respondToClick(event)
    {
        if (event.target.nodeName.toLowerCase() === 'td') {
            event.target.style.backgroundColor = "green";
        }
    }        ChessTable.addEventListener("click", respondToClick);

know i needed to random cells and then collor then. i did it to and works great, i did it using random function from 0-63, then convert the numbers to base 8, because i wanted to compare each cell to the row and column, then split the numbers to know each row and column.

function getRandomArbitrary(min, max)
        {
            return Math.round(Math.random() * (max - min)   min);
        }
    //random numbers
    var a = [];
    for (var j = 0; j < 5; j  ) {
        a[j] = getRandomArbitrary(0, 64)           
    }
    console.log(a)      
    var b = [];
    b = a;
    //convert to base 8
    for (var j = 0; j < 5; j  ) {
       b[j]=b[j].toString(8);
    }

    console.log(b);
    const cells = []

    //seperate the digidt for board

    for (var j = 0; j < 5; j  )
    {
        b[j] = b[j].toString(8);
        var digits = b[j].toString().split('');
        var realDigits = digits.map(Number)
        console.log(realDigits);

        // coloring the random numbers
        if (realDigits[1] != null) {
             cells[j] = ChessTable.rows[realDigits[0]].cells[realDigits[1]];
            cells[j].style.backgroundColor = "yellow";
        }
        else {
            cells[j] = ChessTable.rows[0].cells[realDigits[0]];
            cells[j].style.backgroundColor = "yellow";
        }
    }

that`s work great too.

Now the last problem that i have is that i need to do this. first the computer need to random the cells, but don`t need to show them yet, when there is click in the mouse then the user need to know if the click was on cell that the computer chose randomly.

so i added did this to the respondToClick function.

 function respondToClick(event, cells)
        {
            if (event.target.nodeName.toLowerCase() === 'td')
            {
                event.target.style.backgroundColor = "green";
                if (event.target.nodeName.toLowerCase() == cells[0]) {
                    alert("correct")
                }
            }
         }

in cells i have the "place of the cells(i added a photo) (cells[0] is just for testing, i can use loop there for each click to go over all the cells)

so when i compare the event to the cells[0], i`m getting error. what im missing here?the error

CodePudding user response:

First, let's organize your code better, so it is easier to work with the board.

You are currently making the board using a table, which I don't recommend. Instead, it would be better to use a <div>.

Also, you are using a two-dimensional array, that isn't needed, and can sometimes overcomplicate the code.

I would recommend using a one dimensional array instead.

function makeBoard(height, width, init_callback){
    return Array(height*width).fill(0).map(init_callback);
}

Make board will create an array of the length height * width, and populate it using the callback function.

The callback would look something like this:

function initCell(){
    const cell = document.createElement("div");
    // make changes to cell
    cell.classList.add("cell")
    return cell
}

You can then add the grid to your HTML easily, by using .append().

//  <div id="board" />
const board = document.querySelector("#board");

const pieces = makeBoard(8, 9, initCell);

// append can take multiple elements. Making it easy to add our elements by de-structering our array.
board.append(...pieces); 

Now, to style the board, we don't need to use JavaScript. CSS is very powerful and can easily handle it for us.

.cell {
  height: 40px;
  width: 40px;
  background-color: white;
}

.cell:nth-child(odd){
  background-color: brown;
}

.cell:nth-child(9n 1){
  display: none;
}

#board {
  height:  320px;
  width: 320px;
  display: grid;
  grid-template-columns: repeat(8, 40px);
}

If you look at the precious JS and CSS, our grid is actually 8x9 and not 8x8. This is because, to easily create a chessboard pattern, we are creating a 8x9 board and then removing the 9th cell of each row, to create the chessboard.

Now to add the click events, it's relatively easy.

document.querySelectorAll(".cell").forEach(cell => {
    cell.addEventListener("click", cellClickHandler)
});

That code will set the onClick event on the cells to the cellClickHandler function.

To change the bg-color, when clicked, it would look like this:

function cellClickHandler(e){
    e.target.classList.toggle("green")
}

Now here's a runnable version, to see what we have so far:

function makeBoard(height, width, init_callback){
    return Array(height*width).fill(0).map(init_callback)
}

function initCell(){
    const cell = document.createElement("div");
    // make changes to cell
    cell.classList.add("cell");
    return cell
}

//  <div id="board" />
const board = document.querySelector("#board");

const pieces = makeBoard(8, 9, initCell);
board.append(...pieces);

document.querySelectorAll(".cell").forEach(cell => {
    cell.addEventListener("click", cellClickHandler)
});

function cellClickHandler(e){
    e.target.classList.toggle("green")
}
.cell {
  height: 40px;
  width: 40px;
  background-color: white;
}

.cell:nth-child(odd){
  background-color: brown;
}

.cell:nth-child(9n 1){
  display: none;
  border: none;
}

.green {
  background-color: green !important;
}

#board {
  height:  320px;
  width: 320px;
  display: grid;
  grid-template-columns: repeat(8, 40px);
}
<div id="board" />

CodePudding user response:

You need to use bind or a closure to pass the cells parameter to the handler.

const chessTableClickHandler = respondToClick.bind(null, cells);

ChessTable.addEventListener("click", chessTableClickHandler);

function respondToClick(cells, event)
        {
            if (event.target.nodeName.toLowerCase() === 'td')
            {
                event.target.style.backgroundColor = "green";
                if (event.target.nodeName.toLowerCase() == cells[0]) {
                    alert("correct")
                }
            }
         }
  • Related