文章導覽

我很喜歡wiwi.blog右側文章列表欄,又很喜歡stack的介面,所以我就都把它們縫在一起了。

此方法也是透過AI完成的,我本人能力真的不好沒辦法靠自己完成他。

講的比較簡略,如果有需要可以私信我可以跟你說明的更加詳細。

首先需要在hugo.toml加入組件

1
2
3
4
  [params.widgets]
    homepage = [
      { type = "article-nav", params = {limit = 2000} }
    ]

找出所有post且沒有隱藏的文章

1
2
3
{{ $pages := where $context.Site.RegularPages "Type" "post" }}
{{ $notHidden := where $context.Site.RegularPages "Params.hidden" "!=" true }}
{{ $filtered := ($pages | intersect $notHidden) }}

生成文章列表,{{ .File.BaseFileName }}會根據我的檔名顯示,若想要用標題顯示可以直接改成{{ .Title }}

用檔名我才會有動力去整理文章,不然我原本的檔名都是{date}.md

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<div class="widget-article-nav--list">
    {{ range first $limit $filtered }}
        <div class="article-nav-item">
            <a href="/#article-{{ .File.BaseFileName }}" 
               class="article-nav-link" 
               data-article-id="article-{{ .File.BaseFileName }}">
                {{ .File.BaseFileName }}
            </a>
        </div>
    {{ end }}
</div>

這邊要注意的是,當點擊的文章的時候,會阻止跳轉,然後會取得文章的ID,並找到對應的文章。

1
2
3
4
5
6
        link.addEventListener('click', function(e) {
            e.preventDefault();  // 阻止預設跳轉
            const articleId = this.getAttribute('data-article-id');
            const targetElement = document.getElementById(articleId);
        }
        ...

自動滾動並加上高亮

1
2
  targetElement.scrollIntoView({ behavior: 'smooth' });
  targetElement.classList.add('highlighted');

抄作業的同學這邊請


    {{- $context := .Context -}}
    {{- $limit := default 10 .Params.limit -}}
<section class="widget article-nav">
    <h3 class="widget-title section-title">文章導覽</h3>

    {{ $pages := where $context.Site.RegularPages "Type" "post" }}
    {{ $notHidden := where $context.Site.RegularPages "Params.hidden" "!=" true }}
    {{ $filtered := ($pages | intersect $notHidden) }}
    
    <div class="widget-article-nav--list">
        {{ range first $limit $filtered }}
            <div class="article-nav-item">
                <a href="/#article-{{ .File.BaseFileName }}" class="article-nav-link" data-article-id="article-{{ .File.BaseFileName }}">
                    {{ .File.BaseFileName }}
                </a>
            </div>
        {{ end }}
    </div>
    
    <!-- 其他代碼保持不變 -->
    
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const navLinks = document.querySelectorAll('.article-nav-link');
            
            navLinks.forEach(link => {
                link.addEventListener('click', function(e) {
                    e.preventDefault();
                    const articleId = this.getAttribute('data-article-id');
                    const targetElement = document.getElementById(articleId);
                    
                    if (targetElement) {
                        // 如果在同一頁面
                        if (window.location.pathname === '/' || window.location.pathname === '/index.html') {
                            targetElement.scrollIntoView({ 
                                behavior: 'smooth',
                                block: 'start'
                            });
                            
                            // 添加高亮效果
                            document.querySelectorAll('article[id^="article-"]').forEach(article => {
                                article.classList.remove('highlighted');
                            });
                            targetElement.classList.add('highlighted');
                            
                            // 3秒後移除高亮
                            setTimeout(() => {
                                targetElement.classList.remove('highlighted');
                            }, 3000);
                        } 
                    }
                });
            });
            
            // 如果 URL 中有 hash,在頁面載入時自動滾動
            if (window.location.hash && window.location.hash.startsWith('#article-')) {
                const targetId = window.location.hash.substring(1);
                const targetElement = document.getElementById(targetId);
                if (targetElement) {
                    setTimeout(() => {
                        targetElement.scrollIntoView({ 
                            behavior: 'smooth',
                            block: 'start'
                        });
                        targetElement.classList.add('highlighted');
                        setTimeout(() => {
                            targetElement.classList.remove('highlighted');
                        }, 3000);
                    }, 100);
                }
            }
        });
    </script>
</section>

使用 Hugo 建立
主題 StackJimmy 設計