22.内容扩展:创建“实用网站”导航页

22.内容扩展:创建“实用网站”导航页

前言:功能介绍

本指南将引导您创建一个高度结构化、美观且易于维护的“实用网站”导航页面。我们将实现以下效果:

  1. Tab 切换分类:将您不同类别的网站链接,放入可以点击切换的Tab选项卡中,让页面保持整洁。
  2. 数据集中管理:将所有的链接数据,统一存放在一个独立的 yml 文件中,方便您未来随时增删和修改,而无需触碰页面代码。
  3. 样式自动化:完全利用主题内置的 {% tabs %}{% link %} 外挂标签,自动生成美观的卡片布局,无需您编写任何额外的CSS。

第一步:创建并编辑您的链接数据文件

这是本方案的核心。我们将所有链接数据都存放在这里。

  1. 创建数据文件 (useful_links.yml)
  • 在您博客的 source/_data/ 文件夹内,新建一个名为 useful_links.yml 的文件。
  1. 编辑 useful_links.yml 文件

    • 将您所有的网站链接,按照下面的格式进行分类和整理。您可以创建任意多个分类。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    # source/_data/useful_links.yml

    - category: "前端开发"
    links:
    - name: "MDN Web Docs"
    descr: "前端开发者的权威参考手册"
    link: "https://developer.mozilla.org/zh-CN/"
    avatar: "https://developer.mozilla.org/favicon.ico"
    - name: "CSS-Tricks"
    descr: "关于CSS的一切,技巧、教程和灵感"
    link: "https://css-tricks.com/"
    avatar: "https://css-tricks.com/favicon.ico"

    - category: "设计与灵感"
    links:
    - name: "Dribbble"
    descr: "全球顶尖设计师的作品展示平台"
    link: "https://dribbble.com/"
    avatar: "https://cdn.dribbble.com/assets/favicon-63b2909422b16815e47346142d4d2b56.ico"
    - name: "Pinterest"
    descr: "发现和收藏创意灵感的视觉探索工具"
    link: "https://www.pinterest.com/"
    avatar: "https://www.pinterest.com/favicon.ico"

    - category: "云服务与部署"
    links:
    - name: "Vercel"
    descr: "前端项目的自动化部署与托管平台"
    link: "https://vercel.com/"
    avatar: "https://assets.vercel.com/image/upload/front/favicon/vercel/favicon.ico"
    • 格式说明:最外层是一个列表,每一项(以 - 开头)都包含一个 category(分类名)和一个 links(该分类下的链接列表)。

第二步:创建页面并使用“魔法代码”
  1. 创建页面文件
  • 在终端运行命令: hexo new page awesome-links (或您喜欢的任何名字)。
  1. 修改页面 Front-matter

    • 打开新生成的 source/awesome-links/index.md 文件,设置好它的Front-matter:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ---
    title: 实用网站导航
    date: 2025-06-17 18:00:00
    comments: true
    aside: false
    type: useful_links
    ---


  2. 创建 Pug 模板文件

    • themes/anzhiyu/layout/includes/page/useful_links.pug将下面这段代码完整地复制粘贴进去
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #article-container
    // 添加搜索功能区域
    #useful-links-search-container
    .search-header
    .search-box
    input#useful-links-search(type="text" placeholder="搜索实用网站..." autocomplete="off")
    i.anzhiyufont.anzhiyu-icon-search.search-icon
    .category-filters
    .category-filter.active(data-category="all") 全部
    if site.data.useful_links
    each i in site.data.useful_links
    if i.class_name
    .category-filter(data-category=`${i.class_name}`)= i.class_name
    .search-stats
    span#search-results-count

    .flink
    if site.data.useful_links
    each i in site.data.useful_links
    if i.class_name
    h2(data-category=`${i.class_name}`)!= i.class_name + "(" + i.link_list.length + ")"
    if i.class_desc
    .flink-desc!=i.class_desc
    if i.flink_style === 'anzhiyu'
    div(class=i.lost_contact ? 'anzhiyu-flink-list cf-friends-lost-contact' : 'anzhiyu-flink-list')
    if i.link_list
    each item in i.link_list
    - let color = item.color || ""
    - let tag = item.tag || ""

    .flink-list-item
    if color == "vip" && tag
    span.site-card-tag.vip #[=tag]
    i.light
    else if color == "speed" && tag
    span.site-card-tag.speed #[=ta3g]
    else if tag
    span.site-card-tag(style=`background-color: ${color}`) #[=tag]
    else if item.recommend
    span.site-card-tag 荐
    if i.lost_contact
    a.cf-friends-link(href=url_for(item.link) title=item.name target="_blank")
    if theme.lazyload.enable
    img.no-lightbox(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
    else
    img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
    .flink-item-info
    .flink-item-name.cf-friends-name-lost-contact= item.name
    else
    a.cf-friends-link(href=url_for(item.link) cf-href=url_for(item.link) title=item.name target="_blank")
    if theme.lazyload.enable
    img.cf-friends-avatar.no-lightbox(data-lazy-src=url_for(item.avatar), cf-src=url_for(item.avatar), onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
    else
    img.cf-friends-avatar.no-lightbox(src=url_for(item.avatar) cf-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt=item.name )
    .flink-item-info
    .flink-item-name.cf-friends-name= item.name
    .flink-item-desc(title=item.descr)= item.descr
    else
    .flink-null 暂无实用网站数据
    != page.content
  3. themes/anzhiyu/layout/page.pug新增页面块

    1
    2
    3
    4
    when 'todolist'
    include includes/page/todolist.pug
    when 'useful_links' // 在这里新增
    include includes/page/useful_links.pug
  4. 创建搜索功能的JavaScript文件themes/anzhiyu/source/js/useful-links-search.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    /**
    * 实用网站导航搜索功能
    * Author: Prorise
    */

    const UsefulLinksSearch = {
    data: [],
    currentCategory: 'all',

    init() {
    console.log('初始化实用网站导航搜索功能...');
    this.loadData();
    this.bindEvents();
    this.updateResultsCount();
    },

    loadData() {
    // 从页面中提取网站数据
    const linkItems = document.querySelectorAll('.anzhiyu-flink-list .flink-list-item');
    this.data = [];

    linkItems.forEach((item, index) => {
    const nameEl = item.querySelector('.flink-item-name');
    const descEl = item.querySelector('.flink-item-desc');
    const linkEl = item.querySelector('.cf-friends-link');
    const categoryEl = item.closest('.flink').querySelector('h2');

    if (nameEl && linkEl) {
    this.data.push({
    index: index,
    name: nameEl.textContent.trim(),
    description: descEl ? descEl.textContent.trim() : '',
    link: linkEl.href,
    category: categoryEl ? categoryEl.dataset.category : '',
    element: item,
    categoryElement: categoryEl
    });
    }
    });

    console.log(`加载了 ${this.data.length} 个网站数据`);
    },

    bindEvents() {
    const searchInput = document.getElementById('useful-links-search');
    const categoryFilters = document.querySelectorAll('.category-filter');

    if (searchInput) {
    // 搜索输入框事件
    searchInput.addEventListener('input', this.debounce((e) => {
    this.performSearch(e.target.value);
    }, 300));

    // 回车键搜索
    searchInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
    e.preventDefault();
    this.performSearch(e.target.value);
    }
    });
    }

    // 分类筛选事件
    categoryFilters.forEach(filter => {
    filter.addEventListener('click', (e) => {
    const category = e.target.dataset.category;
    this.filterByCategory(category);
    this.updateActiveFilter(e.target);

    // 如果不是"全部",则滚动到对应分类
    if (category !== 'all') {
    this.scrollToCategory(category);
    }
    });
    });
    },

    performSearch(keyword) {
    keyword = keyword.toLowerCase().trim();

    if (keyword === '') {
    this.showAllItems();
    this.updateResultsCount();
    return;
    }

    let visibleCount = 0;
    const categoryVisibility = {};

    this.data.forEach(item => {
    const matchName = item.name.toLowerCase().includes(keyword);
    const matchDesc = item.description.toLowerCase().includes(keyword);
    const isVisible = matchName || matchDesc;

    // 根据当前分类过滤
    const categoryMatch = this.currentCategory === 'all' || item.category === this.currentCategory;
    const shouldShow = isVisible && categoryMatch;

    if (shouldShow) {
    visibleCount++;
    // 高亮显示匹配的关键词
    this.highlightKeyword(item, keyword);
    item.element.classList.remove('hidden');

    // 记录该分类下有可见项目
    categoryVisibility[item.category] = true;
    } else {
    item.element.classList.add('hidden');
    }
    });

    // 显示/隐藏分类标题
    this.toggleCategoryTitles(categoryVisibility);
    this.updateResultsCount(visibleCount, keyword);
    },

    filterByCategory(category) {
    this.currentCategory = category;
    const searchInput = document.getElementById('useful-links-search');
    const keyword = searchInput ? searchInput.value : '';

    if (keyword) {
    this.performSearch(keyword);
    } else {
    this.showCategoryItems(category);
    }
    },

    showCategoryItems(category) {
    let visibleCount = 0;
    const categoryVisibility = {};

    this.data.forEach(item => {
    const shouldShow = category === 'all' || item.category === category;

    if (shouldShow) {
    visibleCount++;
    item.element.classList.remove('hidden');
    categoryVisibility[item.category] = true;
    } else {
    item.element.classList.add('hidden');
    }
    });

    this.toggleCategoryTitles(categoryVisibility);
    this.updateResultsCount(visibleCount);
    },

    showAllItems() {
    this.data.forEach(item => {
    item.element.classList.remove('hidden');
    this.removeHighlight(item);
    });

    // 显示所有分类标题
    document.querySelectorAll('.flink h2').forEach(title => {
    title.style.display = '';
    });
    },

    highlightKeyword(item, keyword) {
    const nameEl = item.element.querySelector('.flink-item-name');
    const descEl = item.element.querySelector('.flink-item-desc');

    if (nameEl) {
    nameEl.innerHTML = this.highlightText(item.name, keyword);
    }
    if (descEl) {
    descEl.innerHTML = this.highlightText(item.description, keyword);
    }
    },

    removeHighlight(item) {
    const nameEl = item.element.querySelector('.flink-item-name');
    const descEl = item.element.querySelector('.flink-item-desc');

    if (nameEl) {
    nameEl.textContent = item.name;
    }
    if (descEl) {
    descEl.textContent = item.description;
    }
    },

    highlightText(text, keyword) {
    if (!text || !keyword) return text;

    const regex = new RegExp(`(${keyword})`, 'gi');
    return text.replace(regex, '<span class="search-highlight">$1</span>');
    },

    toggleCategoryTitles(categoryVisibility) {
    document.querySelectorAll('.flink h2').forEach(title => {
    const category = title.dataset.category;
    if (this.currentCategory === 'all') {
    title.style.display = categoryVisibility[category] ? '' : 'none';
    } else {
    title.style.display = category === this.currentCategory ? '' : 'none';
    }
    });
    },

    updateActiveFilter(activeFilter) {
    document.querySelectorAll('.category-filter').forEach(filter => {
    filter.classList.remove('active');
    });
    activeFilter.classList.add('active');
    },

    scrollToCategory(categoryName) {
    const targetTitle = document.querySelector(`h2[data-category="${categoryName}"]`);
    if (targetTitle && typeof anzhiyu !== 'undefined' && anzhiyu.scrollToDest) {
    // 使用主题自带的平滑滚动函数
    const targetTop = anzhiyu.getEleTop(targetTitle) - 120; // 预留搜索框高度
    anzhiyu.scrollToDest(targetTop, 500);
    } else if (targetTitle) {
    // 备用滚动方案
    targetTitle.scrollIntoView({
    behavior: 'smooth',
    block: 'start',
    inline: 'nearest'
    });
    }
    },

    updateResultsCount(count = null, keyword = '') {
    const statsEl = document.getElementById('search-results-count');
    if (!statsEl) return;

    if (count === null) {
    count = this.data.filter(item => !item.element.classList.contains('hidden')).length;
    }

    if (keyword) {
    statsEl.textContent = `找到 ${count} 个包含 "${keyword}" 的网站`;
    } else if (this.currentCategory !== 'all') {
    statsEl.textContent = `${this.currentCategory} 分类下共 ${count} 个网站`;
    } else {
    statsEl.textContent = `共 ${count} 个实用网站`;
    }
    },

    // 防抖函数
    debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
    const later = () => {
    clearTimeout(timeout);
    func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    };
    }
    };

    // 页面加载完成后初始化搜索功能
    document.addEventListener('DOMContentLoaded', () => {
    // 确保在实用网站导航页面才初始化
    if (document.getElementById('useful-links-search-container')) {
    UsefulLinksSearch.init();
    }
    });

    // 支持 PJAX 刷新
    if (typeof anzhiyu !== 'undefined') {
    anzhiyu.addGlobalFn('pjax', () => {
    if (document.getElementById('useful-links-search-container')) {
    setTimeout(() => {
    UsefulLinksSearch.init();
    }, 100);
    }
    });
    }

    6.创建对应的样式文件:themes/anzhiyu/source/css/useful-links-search.css

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    /**
    * 实用网站导航搜索功能样式
    * 适配 AnZhiYu 主题
    */

    /* 搜索容器 */
    #useful-links-search-container {
    margin-bottom: 2rem;
    padding: 1.5rem;
    background: var(--anzhiyu-card-bg);
    border-radius: 12px;
    border: var(--style-border);
    box-shadow: var(--anzhiyu-shadow-border);
    transition: all 0.3s ease;
    }

    #useful-links-search-container:hover {
    border: var(--style-border-hover);
    box-shadow: var(--anzhiyu-shadow-theme);
    }

    /* 搜索头部 */
    .search-header {
    margin-bottom: 1rem;
    }

    /* 搜索框样式 */
    .search-box {
    position: relative;
    margin-bottom: 1rem;
    }

    .search-box input {
    width: 100%;
    padding: 0.75rem 3rem 0.75rem 1rem;
    border: var(--style-border);
    border-radius: 8px;
    background: var(--anzhiyu-secondbg);
    color: var(--anzhiyu-fontcolor);
    font-size: 1rem;
    transition: all 0.3s ease;
    outline: none;
    }

    .search-box input:focus {
    border: var(--style-border-hover);
    box-shadow: 0 0 0 3px rgba(var(--anzhiyu-main-rgb), 0.1);
    }

    .search-box input::placeholder {
    color: var(--anzhiyu-secondtext);
    opacity: 0.8;
    }

    /* 搜索图标 */
    .search-icon {
    position: absolute;
    right: 1rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--anzhiyu-secondtext);
    font-size: 1.1rem;
    pointer-events: none;
    transition: color 0.3s ease;
    }

    .search-box input:focus + .search-icon {
    color: var(--anzhiyu-main);
    }

    /* 分类过滤器 */
    .category-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    }

    .category-filter {
    padding: 0.5rem 1rem;
    background: var(--anzhiyu-secondbg);
    border: var(--style-border);
    border-radius: 20px;
    cursor: pointer;
    transition: all 0.3s ease;
    font-size: 0.9rem;
    color: var(--anzhiyu-fontcolor);
    user-select: none;
    white-space: nowrap;
    }

    .category-filter:hover {
    background: var(--anzhiyu-main);
    color: var(--anzhiyu-white);
    border-color: var(--anzhiyu-main);
    transform: translateY(-1px);
    }

    .category-filter.active {
    background: var(--anzhiyu-main);
    color: var(--anzhiyu-white);
    border-color: var(--anzhiyu-main);
    box-shadow: 0 2px 8px rgba(var(--anzhiyu-main-rgb), 0.3);
    }

    /* 搜索统计信息 */
    .search-stats {
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: var(--style-border);
    }

    #search-results-count {
    color: var(--anzhiyu-secondtext);
    font-size: 0.9rem;
    font-weight: 500;
    }

    /* 搜索结果高亮 */
    .search-highlight {
    background: var(--anzhiyu-main);
    color: var(--anzhiyu-white);
    padding: 2px 4px;
    border-radius: 3px;
    font-weight: bold;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    }

    /* 隐藏不匹配的项目 */
    .flink-list-item.hidden {
    display: none !important;
    }

    .flink h2.hidden {
    display: none !important;
    }

    /* 响应式设计 */
    @media (max-width: 768px) {
    #useful-links-search-container {
    padding: 1rem;
    margin-bottom: 1.5rem;
    }

    .search-box input {
    padding: 0.6rem 2.5rem 0.6rem 0.8rem;
    font-size: 0.9rem;
    }

    .search-icon {
    right: 0.8rem;
    font-size: 1rem;
    }

    .category-filter {
    padding: 0.4rem 0.8rem;
    font-size: 0.85rem;
    }

    .category-filters {
    gap: 0.4rem;
    }

    #search-results-count {
    font-size: 0.85rem;
    }
    }

    @media (max-width: 480px) {
    #useful-links-search-container {
    padding: 0.8rem;
    }

    .search-box input {
    padding: 0.5rem 2rem 0.5rem 0.6rem;
    font-size: 0.85rem;
    }

    .category-filter {
    padding: 0.3rem 0.6rem;
    font-size: 0.8rem;
    }
    }

    /* 深色模式适配 */
    [data-theme='dark'] #useful-links-search-container {
    border-color: var(--style-border);
    }

    [data-theme='dark'] .search-box input {
    background: var(--anzhiyu-secondbg);
    border-color: var(--style-border);
    color: var(--anzhiyu-fontcolor);
    }

    [data-theme='dark'] .category-filter {
    background: var(--anzhiyu-secondbg);
    border-color: var(--style-border);
    color: var(--anzhiyu-fontcolor);
    }

    /* 动画效果 */
    .category-filter {
    position: relative;
    overflow: hidden;
    }

    .category-filter::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: left 0.5s;
    }

    .category-filter:hover::before {
    left: 100%;
    }

    /* 搜索框聚焦动画 */
    .search-box {
    position: relative;
    }

    .search-box::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 0;
    height: 2px;
    background: var(--anzhiyu-main);
    transition: all 0.3s ease;
    transform: translateX(-50%);
    }

    .search-box input:focus ~ ::after {
    width: 100%;
    }

    /* 加载状态 */
    .search-loading {
    opacity: 0.6;
    pointer-events: none;
    }

    .search-loading .search-icon::before {
    content: '\e6cd'; /* loading icon */
    animation: spin 1s linear infinite;
    }

    @keyframes spin {
    from { transform: translateY(-50%) rotate(0deg); }
    to { transform: translateY(-50%) rotate(360deg); }
    }

    /* 无结果状态 */
    .no-results-message {
    text-align: center;
    padding: 2rem;
    color: var(--anzhiyu-secondtext);
    font-size: 1rem;
    }

    .no-results-message i {
    font-size: 3rem;
    margin-bottom: 1rem;
    opacity: 0.5;
    }

    /* 滚动到顶部按钮增强(搜索时显示) */
    .search-active #nav-totop {
    opacity: 1 !important;
    transform: translateX(-58px) !important;
    }

    /* 分类标题动画 */
    .flink h2 {
    transition: all 0.3s ease;
    }

    .flink h2[style*="display: none"] {
    opacity: 0;
    transform: translateY(-10px);
    }

    /* 搜索结果项目动画 */
    .flink-list-item {
    transition: all 0.3s ease;
    }

    .flink-list-item.hidden {
    opacity: 0;
    transform: scale(0.9) translateY(-10px);
    pointer-events: none;
    }

    /* 高亮动画 */
    .search-highlight {
    animation: highlight-pulse 1s ease-in-out;
    }

    @keyframes highlight-pulse {
    0% {
    box-shadow: 0 0 0 0 rgba(var(--anzhiyu-main-rgb), 0.7);
    }
    70% {
    box-shadow: 0 0 0 6px rgba(var(--anzhiyu-main-rgb), 0);
    }
    100% {
    box-shadow: 0 0 0 0 rgba(var(--anzhiyu-main-rgb), 0);
    }
    }

    7.可以使用inject直接注入js和css,但是我们这里就用自己写的按需载入js脚本了

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    /**
    * 按需加载资源管理器
    * 用于优化网站性能,只在需要时加载特定资源
    */

    class ResourceLoader {
    constructor() {
    this.loadedCSS = new Set();
    this.loadedJS = new Set();
    }

    /**
    * 动态加载CSS文件
    * @param {string} href - CSS文件路径
    * @param {string} id - 可选的link元素ID
    */
    loadCSS(href, id = null) {
    if (this.loadedCSS.has(href) || document.querySelector(`link[href="${href}"]`)) {
    return Promise.resolve();
    }

    return new Promise((resolve, reject) => {
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = href;
    if (id) link.id = id;

    link.onload = () => {
    this.loadedCSS.add(href);
    resolve();
    };
    link.onerror = reject;

    document.head.appendChild(link);
    });
    }

    /**
    * 动态加载JS文件
    * @param {string} src - JS文件路径
    * @param {string} id - 可选的script元素ID
    */
    loadJS(src, id = null) {
    if (this.loadedJS.has(src) || document.querySelector(`script[src="${src}"]`)) {
    return Promise.resolve();
    }

    return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    if (id) script.id = id;

    script.onload = () => {
    this.loadedJS.add(src);
    resolve();
    };
    script.onerror = reject;

    document.body.appendChild(script);
    });
    }

    /**
    * 检测页面内容并按需加载相关资源
    */
    autoDetectAndLoad() {
    // 检测是否为首页
    if (window.location.pathname === '/' || window.location.pathname === '/index.html') {
    // 修复:index_media.css 现在由头部优先加载,只需加载JS
    this.loadJS('/js/index_media.js', 'index-media-script');
    }

    // 检测是否为文章页
    if (document.querySelector('#post') || document.querySelector('.post-content')) {
    this.loadCSS('/css/custom-comment.css', 'custom-comment-style');
    this.loadCSS('/custom/css/tip_style.css', 'tip-style');
    this.loadJS('/js/fixed_comment.js', 'fixed-comment-script');
    this.loadJS('/custom/js/tip_main.js', 'tip-main-script');
    }

    // 检测B站视频内容
    if (document.querySelector('iframe[src*="bilibili.com"]') ||
    document.querySelector('iframe[src*="player.bilibili.com"]')) {
    this.loadCSS('/css/bilibili.css', 'bilibili-style');
    }

    // 检测代码块
    if (document.querySelector('pre code') || document.querySelector('.highlight')) {
    this.loadCSS('/custom/css/sandbox_style.css', 'sandbox-style');
    }

    // 检测评论区
    if (document.querySelector('#twikoo') ||
    document.querySelector('#waline') ||
    document.querySelector('#valine')) {
    this.loadJS('/js/comments.js', 'comments-script');
    }

    // 检测即刻短文页面
    if (window.location.pathname.includes('/essay/') || document.querySelector('#essay_page')) {
    this.loadCSS('/css/essay-style.css', 'essay-style');
    }

    // 检测待办清单页面
    if (window.location.pathname.includes('/todolist/') || document.querySelector('#todolist-box')) {
    this.loadCSS('/custom/css/todolist.css', 'todolist-style');
    }

    // 检测实用网站导航页面
    if (window.location.pathname.includes('/awesome-links/') ||
    document.querySelector('#useful-links-container') ||
    document.querySelector('.useful-links-page')) {
    this.loadCSS('/css/useful-links-search.css', 'useful-links-search-style');
    this.loadJS('/js/useful-links-search.js', 'useful-links-search-script');
    }

    // 检测侧边栏相关功能
    if (document.querySelector('#sidebar')) {
    this.loadCSS('/custom/css/schedule.css', 'schedule-style');
    this.loadCSS('/custom/css/background-box.css', 'background-style');
    this.loadJS('https://cdn.jsdelivr.net/npm/winbox@0.2.82/dist/winbox.bundle.min.js', 'winbox-lib')
    .then(() => this.loadJS('/custom/js/chineselunar.js', 'chineselunar-script'))
    .then(() => this.loadJS('/custom/js/schedule.js', 'schedule-script'))
    .then(() => this.loadJS('/custom/js/background-box.js', 'background-script'))
    .catch(err => console.warn('侧边栏脚本加载失败:', err));
    }
    }
    }

    // 创建全局实例
    window.resourceLoader = new ResourceLoader();

    // 页面加载完成后自动检测
    document.addEventListener('DOMContentLoaded', () => {
    window.resourceLoader.autoDetectAndLoad();
    });

    // 为PJAX提供支持
    document.addEventListener('pjax:complete', () => {
    window.resourceLoader.autoDetectAndLoad();
    });

第三步:在菜单中添加入口
  1. 打开您主题的配置文件 (_config.yml)。
  2. menu: 部分添加一个新链接,指向我们刚刚创建的页面。
    1
    2
    3
    4
    5
    menu:
    # ...
    百宝箱: # 或者您喜欢的任何名字
    实用网站: /awesome-links/ || anzhiyu-icon-compass
    # ...