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>