Featured image of post Hugo Stack 主題創建返回頂部按鈕

Hugo Stack 主題創建返回頂部按鈕

本文為英文版本的機器翻譯

這篇文章是我的個人筆記。這裡的程式碼和反思主要用於學習,可能並不總是正確的或可用於生產。

在嘗試我的部落格時,我認為適用於行動裝置的浮動目錄 (TOC) 按鈕是一個好主意(特別是對於包含大量內容的貼文)。然而在網上搜索後,我找不到關於現有實現的太多資訊。因此,我決定將其分解為更小的步驟,從一個更簡單的功能開始:建立一個返回頂部(back-to-top)按鈕。

以下是我的做法。

新增按鈕的 HTML

我正在使用 Stack 主題,位於layouts/footer有一個方便的custom.html文件,非常適合添加自訂功能,而無需修改主題的核心文件。

這是我添加的程式碼:

<div id="back-to-top">
  <button>
    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" 
      viewBox="0 0 24 24" fill="none" stroke="currentColor"
      stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
      <polyline points="18 15 12 9 6 15"></polyline>
    </svg>
  </button>
</div>

使用 CSS 設定按鈕樣式

為了使按鈕適應淺色和深色主題,我更新了scss/partials/footer.scss:

#back-to-top {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 1000;
    display: none;
}

#back-to-top button {
    padding: 8px;
    border: none;
    border-radius: 8px;
    background-color: var(--back-to-top-bg);
    box-shadow: 0 3px 5px var(--back-to-top-shadow);
    cursor: pointer;
    width: 36px;
    height: 36px;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: all 0.3s ease;
}

#back-to-top button:hover {
    background-color: var(--back-to-top-bg-hover);
    box-shadow: 0 5px 8px var(--back-to-top-shadow-hover);
    transform: translateY(-2px);
}

#back-to-top button svg {
    width: 16px;
    height: 16px;
    // fill: var(--back-to-top-arrow);
    stroke: var(--back-to-top-arrow);
    transition: stroke 0.3s ease;
}

#back-to-top button:hover svg {
    // fill: var(--back-to-top-arrow);
    stroke: var(--back-to-top-arrow);
}

我將定義淺色和深色主題的顏色變量更新在variables.scss

/* 
*   Footer back to top style
*/
:root {
    --back-to-top-bg: #f9f9fc;
    --back-to-top-bg-hover: #ececf6;
    --back-to-top-arrow: #2c3e50;
    --back-to-top-shadow: rgba(0, 0, 0, 0.1);
    --back-to-top-shadow-hover: rgba(0, 0, 0, 0.15);
}

[data-scheme="dark"] {
    --back-to-top-bg: #424242;
    --back-to-top-bg-hover: #383838;
    --back-to-top-arrow: rgba(255, 255, 255, 0.7);
    --back-to-top-shadow: rgba(0, 0, 0, 0.3);
    --back-to-top-shadow-hover: rgba(0, 0, 0, 0.5);
}

使用 JS 實現功能

下一步是讓按鈕發揮作用。我想要它:

  1. 根據捲動位置顯示或隱藏(您可以在其中修改值)。
  2. 單擊時平滑滾動到頂部。

為了實現這一點,我在footer/components/script.html中添加了以下 JavaScript :

<script>
    document.addEventListener("DOMContentLoaded", function () {
        const backToTop = document.getElementById("back-to-top");

        // Show or hide the button on scroll
        window.addEventListener("scroll", function () {
            if (window.scrollY > 400) {
                backToTop.style.display = "block";
            } else {
                backToTop.style.display = "none";
            }
        });

        // Scroll smoothly to the top
        backToTop.addEventListener("click", function () {
            window.scrollTo({ top: 0, behavior: "smooth" });
        });
    });
</script>

反思與收穫

從這種實踐中得到的一個有趣的收穫是了解使用addEventListener相對內聯事件處理程序(如onscrollonclick)的優勢。

addEventListener

  1. 支援多個事件監聽器,這意味著將來我們可以向同一事件添加其他函數,而無需覆蓋現有的處理程序。
  2. 透過將事件註冊與 HTML 和其他 JavaScript 邏輯分開,允許更清晰的程式碼。

這裡函數被使用了兩次,兩者都有不同的作用。

外部addEventListener("DOMContentLoaded")確保腳本在 DOM 完全載入和解析後運行。這很重要,因為如果 DOM 尚未構建,則document.getElementById("back-to-top")可能會返回null。如果沒有這個監聽,後續程式碼將會失敗。

內部addEventListener("scroll")監聽使用者滾動頁面。它根據滾動位置動態切換按鈕的可見性,確保它僅在需要時出現。

有用的連結

在網上搜尋實現時,我發現了一些有用的連結可供參考。