How to create an element in just one div with the same class of another

57 views Asked by At

I'm creating a tic-tac-toe game where each cell is another tic-tac-toe game, so I created a script that creates html elements, but now I'm going to create an svg of an X or O in the cell that the player clicked on, so I tried to do it like onclick="x()" but when i click in whatever cell, the svg element is created in the frist cell. (I also didn't check if there alread is an X or O in the cell).

js:

<script>
    function create_elements_from_html(n, html){
        const template = document.createElement("template")
        let htmlaux = ``
        for (a = 0; a < n; a += 1){
            htmlaux += html
        }

        template.innerHTML = htmlaux
        return template.content;
    }
    let turn = "x"
    function play(){
        if (turn == "x"){
                let x = create_elements_from_html(1, `<svg viewBox="0 0 100 100"> <path class="x_cell_path" d="M 10 10 L 90 90 Z M 10 90 L 90 10"> </svg>`)
                turn = "o"
                return document.querySelector(".cell").appendChild(x)
        }
        else{
                let o = create_elements_from_html(1, `<svg viewBox="0 0 100 100"> <circle class="o_cell_path" r="40" cx="50" cy="50"> </svg>`)
                return document.querySelector(".cell").appendChild(o)
                turn = "x"
        }
    }

    let big_board = create_elements_from_html(1, 
        `<div class="big_board">

            <svg class="small_board_svg" viewBox="0 0 100 100">
                <path class="big_board_path" d="M 33.33333 0 l 0 100 M 66.66666 0 l 0 100 M 0 33.33333 l 100 0 M 0 66.66666 l 100 0">

            </svg>
        </div>`)

    document.body.appendChild(big_board)

    let small_board = create_elements_from_html(9, 
        `<div class="small_board">
            <svg class="small_board_svg" viewBox="0 0 100 100">

                <path class="small_board_path" d="M 33.33333 0 l 0 100 M 66.66666 0 l 0 100 M 0 33.33333 l 100 0 M 0 66.66666 l 100 0">

            </svg>
        </div>`)
    document.querySelector(".big_board").appendChild(small_board)

    for (let i = 0; i < 9; i++) {
        let cell = create_elements_from_html(1, `
        <div class="cell" data-cell onclick="play()">
        </div>`)
        document.querySelectorAll(".small_board").forEach((board) => board.appendChild(cell.cloneNode(true)))
    }
</script>

I want that when I click in the [0, 1] cell, the [0, 1] cell is filled with a X or O, but now that isn't woking

1

There are 1 answers

0
Barmar On

play() should accept the element that was clicked on as a parameter, it can then append the SVG to that element.

function play() {
  let svg;
  if (turn == "x") {
    svg = create_elements_from_html(1, `<svg viewBox="0 0 100 100"> <path class="x_cell_path" d="M 10 10 L 90 90 Z M 10 90 L 90 10"> </svg>`)
    turn = "o"
  } else {
    svg = create_elements_from_html(1, `<svg viewBox="0 0 100 100"> <circle class="o_cell_path" r="40" cx="50" cy="50"> </svg>`)
    turn = "x"
  }
  cell.appendChild(svg);
}
//...
for (let i = 0; i < 9; i++) {
  let cell = create_elements_from_html(1, `
      <div class="cell" data-cell onclick="play(this)">
      </div>`)  document.querySelectorAll(".small_board").forEach((board) => board.appendChild(cell.cloneNode(true)))
}