iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
自我挑戰組

網站主題切換功能系列 第 11

Day11:重構 JavaScript

  • 分享至 

  • xImage
  •  

前言

昨天,我成功實現了主題預覽功能,但在我撰寫程式碼的過程中,我發現自己花了許多時間尋找需要的程式碼,這讓我寫程式的效率變差了。所以,在我完成主題預覽功能後,我決定進行程式碼重構,提高程式的可讀性。

今天的主要的內容就是解釋 JavaScript 程式碼的重構過程及重構的重點。

JavaScript 程式碼重構

在撰寫主題預覽的功能時,我注意到三個我覺得可以改進的地方:

  1. constructor() 內的程式碼過於冗長
  2. setupEventListeners() 方法中的事件監聽器過多,尤其是主題按鈕的部分,大部分程式碼都是重複的
  3. 我決定將事件監聽器中的執行內容提取為獨立方法

重構 constructor()

我發現,由於所有的初始值設定都放在 constructor() 中,導致我 constructor() 的程式碼變得太長了。當我想要返回修改某處的程式碼時,必須一行一行看,才能找到我需要的程式碼,耗費我許多時間。考慮到我之後還有其他的功能需要實現,我決定將元素的抓取放到 initializeElements() 方法中,並在 constructor() 中初始化 initializeElements() 方法。

constructor() {
    this.initializeElements();
    this.setupEventListeners();
    this.nowTheme = "default-theme";
}

重構 setupEventListeners() 中的主題按鈕

首先,先來看一下主題按鈕的原始程式碼:

this.defaultThemeButton.addEventListener("click", () => {
  this.setTheme("default-theme");
});
this.lightThemeButton.addEventListener("click", () => {
  this.setTheme("light-theme");
});
this.nightThemeButton.addEventListener("click", () => {
  this.setTheme("night-theme");
});

this.natureThemeButton.addEventListener("click", () => {
  this.setTheme("nature-theme");
});

通過上面的程式碼,可以觀察到程式碼幾乎完全重複。所以,我將它們提取到一個新的方法 setupThemeButtons() 中。

首先,我先將主題按鈕與主題名稱相關聯並存放到物件中:

const themes = {
  defaultThemeButton: "default-theme",
  lightThemeButton: "light-theme",
  nightThemeButton: "night-theme",
  natureThemeButton: "nature-theme",
};

然後,使用 for 迴圈遍歷 themes 物件。當程式執行時,button 變數將獲取對應的按鈕元素,並且為它添加事件監聽器。在點擊事件的監聽器中,當按鈕被點擊時,就會將 nowTheme 設置為與當前按鈕相關的主題名稱。最後調用 setTheme() 方法設定網頁主題。

for (const [buttonId, themeName] of Object.entries(themes)) {
  const button = this.getElement(`#${buttonId}`);
  button.addEventListener("click", () => {
    this.nowTheme = themeName;
    this.setTheme(this.nowTheme);
  });
}

重構剩餘的 setupEventListeners() 程式碼

接下來,關於 setupEventListeners(),ChatGPT 建議我將事件監聽器中的程式碼提取成方法。雖然剩下的事件監聽器程式碼不是很長,但我還是決定重構程式碼。這是因為當我將它們提取成為方法後,我可以更輕鬆尋找和修改程式碼,不用每次都在 setupEventListeners() 中一行一行尋找。

因此,我將剩餘四個事件監聽器的程式碼提取成方法:

 setupEventListeners() {
    // 開啟側邊欄事件
    this.openSidebarButton.addEventListener("click", () => this.openSidebar());

    // 關閉側邊欄事件
    this.closeSidebarButton.addEventListener("click", () =>
      this.closeSidebar()
    );

    // 待辦事項輸入表單事件
    this.todoForm.addEventListener("submit", (e) =>
      this.handleTodoFormSubmit(e)
    );

    this.themeOptions.forEach((option) => this.setupThemeOptionEvents(option));

    // 背景色切換
    this.toggleThemeButton.addEventListener("click", () =>
      this.toggleSubSettingList()
    );
  }

這樣,當我要尋找相對應的方法時,我就可以直接在 VSCode 的 OUTLINE 中尋找方法了!
https://ithelp.ithome.com.tw/upload/images/20230921/20162569OzTAYoKvXN.png

Github 連結

github: ThemeTasker code
ThemeTasker 靜態網頁


上一篇
Day10:網頁主題預覽
下一篇
Day12:字體選擇和分支設定
系列文
網站主題切換功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言