TicTacToe Events

by WebComponents

HTML

<my-board></my-board>
<hr>
<my-board></my-board>

<script>
  class GameComponent extends HTMLElement {
  	constructor(html){
      super().attachShadow({mode:"open"}).innerHTML = html;
    }
    dispatch({ from = this, eventname, detail = {} }) {
      from.dispatchEvent(new CustomEvent(eventname, {
        composed: true, bubbles: true, detail
      }));
    }
    listen({at = this,eventname,func }) {
      at.addEventListener(eventname, func);
    }
  }
  customElements.define("my-board", class extends GameComponent {
    constructor() {
      super(`<style>:host{display:grid;grid:repeat(3,20px)/repeat(3,60px);gap:1px}</style>` +
        "green,red,blue,orange,olive,tan,teal,yellow,lime"
        .split(",").map(color => `<my-tile>${color}</my-tile>`).join(""));
    }
    connectedCallback() {
      this.listen({ at:this, eventname:"tileclicked",
                    func: (evt) => {
                                //console.log(evt.target,evt.composedPath());
                                this.dispatch({ from: this, eventname: "colortile",
                                                detail: { color: evt.detail.color }})}})
    }
  });
  customElements.define("my-tile", class extends GameComponent {
    constructor() {
      super(`<style>:host{text-align:center;cursor:pointer}</style><slot></slot>`);
    }
    connectedCallback() {
    	console.log(21,this);
    	console.log(22,this.shadowRoot.host);
    	console.log(23,this.getRootNode());
    	console.log(24,this.getRootNode().host);
    	console.log(25,this.getRootNode({composed:true}));
      
      this.onclick = () => this.dispatch({ from: this, eventname: "tileclicked",
                                           detail: { color: this.innerText }});
      this.listen({
                   at: this.getRootNode().host.closest("my-board"),
                   eventname: "colortile",
                   func: (evt) => this.style.background = evt.detail.color });
    }
  });
</script>