實作筆記
在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。然後按次序完成這些步驟:
- this.injectCSS();
- this.renderDOM();
- this.cacheDOM();
- this.bindEvents();
- 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的內容中讀取棋譜數據。
歡迎下載
| 文檔名 | |
| 大小 | |
Pages: 1 2