Search code examples
javascriptwebpackweb-component

querySelectorAll not selecting elements within shadowRoot


I’m trying to create a tic-tac-toe game using Webpack and Web Component.

I need to select a div tag having cell class within shadowRoot at place-mark component, then update innerText to O/X depending on Turn calculated by another function.

The logic is working fine but I cannot select the right components to update the HTML view, so the user could see current status of the selected areas.

Here's my simplified HTML code:

<div class="board" id="board">
    <place-mark data-cell></place-mark>
</div>

Here’s my simplified component code:

const template = document.createElement("template");

template.innerHTML = `<div class="cell" />`;

export default class PlaceMark extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: "open" });
        this.shadowRoot.appendChild(
            template.content.cloneNode(true)
        );
    }
}

window.customElements.define(
    "place-mark",
    PlaceMark
);

Here’s my simplified JS code:

const X_CLASS = "x";
const CIRCLE_CLASS = "circle";
const cellElements = document.querySelectorAll('[data-cell]');
const board = document.getElementById("board");
let circleTurn;

function startGame() {
    cell.addEventListener("click", handleClick, { once: true });});
}

function handleClick(e) {
    const cell = e.target;
    const currentClass = circleTurn
        ? CIRCLE_CLASS
        : X_CLASS;
    placeMark(cell, currentClass);
    if (checkWin(currentClass)) {
        endGame(false);
    } else if (isDraw()) {
        endGame(true);
    } else {
        swapTurns();
        setBoardHoverClass();
    }
}

function placeMark(cell, currentClass) {
    cell.classList.add(currentClass);
}

If you need full version of codes above, Here's my project:

https://github.com/nazaninsnr/TicTacToe


Solution

  • you can simply remove shadowRoot from your code

    it would give you the chance to have access to all the elements and querySelect what you want.

    export default class PlaceMark extends HTMLElement {
    constructor() {
    super();
    this.appendChild(template.content.cloneNode(true));}}
    window.customElements.define("place-mark", PlaceMark);