Ejcees對象化

實作筆記

在gemini的幫助下,我基本明白了對象化的具體步驟。

首先把所有的初始化變量都寫到constructor()中,將let和const都用this.替換。

前四行長這樣:

class Ejcees {
  constructor(container, mode) {
    this.container = container;
    this.mode = mode;
    this.initialTextContent = this.container.textContent ? this.container.textContent.trim() : '';

同時把所有的函式都寫到Class的下方,去掉function。然後按次序完成這些步驟:

  1. this.injectCSS();
  2. this.renderDOM();
  3. this.cacheDOM();
  4. this.bindEvents();
  5. this.initGame();

一,加入CSS

在第一行寫上if (Ejcees.cssInjected) return;,最後一行是Ejcees.cssInjected = true;,這樣就能保證同一個頁面即使有多個實例,CSS也只加入一次。

二,渲染DOM

根據不同模式,加入不同的DOM。其中mini模式的DOM需大幅重寫。

gemini建議要在不同的svg中的元素的id加入實例序號以避免衝突:

所有的 id="tile0" 要改成 id="tile0-${this.instanceId}"

但是我沒有這樣做,我的辦法是,當mini模式時,頁面上可能存在多個實例,則把svg裝進<object>中。

三,拿到DOM

把Document.querySelector(...)改成this.container.querySelector(...)。

因為上一步的mini模式把svg放進了<object>中,所以gemini建議要這樣做:

    if (this.mode === 'mini') {
      this.cacheDOM().then(() => {
        this.bindEvents();
        this.initGame();
      });
    } else {
      this.cacheDOM();
      this.bindEvents();
      this.initGame();
    }

四,綁定事件

我把main和single的事件仍然綁定在document上,但把mini綁定在容器上(this.container),因為一個頁面上會有多個mini窗口。

當希望一個元素能被點擊事件激活時,就給它加上屬性tabindex="-1"

<object>是不可激活的,因此CSS要加入pointer-events: none;。當它被點擊時則會穿過它,激活它下方的元素。

五,遊戲初始化

在頁面打開時,根據條件從url、localStorage或.ejcees的內容中讀取棋譜數據。

歡迎下載

文檔名
大小

Leave a Comment