4 April 2025 - 字数统计：3692 - 阅读大约需要12分钟 - Hits: Loading...

# 最近对博客搜索功能的优化记录

by mayx

这是一篇创建于 天前的文章，其中的信息可能已经有所发展或是发生改变。

AI摘要

这篇文章记录了作者对博客搜索功能进行优化的过程。起因是作者在搜索使用同样模板的博客时，发现许多结果是简历或作品集，而非博客。作者通过搜索关键词和标签，受到其他博主的启发，决定改进搜索功能，使其能够筛选出带有特定标签的文章，并添加了高亮关键词的标记。此外，作者还实现了随机跳转文章、文章标题锚链接以及链接到原始Markdown文件等功能，强调了博客代码和网站功能对于展示个人技术的重要性。整个过程中，作者在借鉴他人经验的同时，也表达了对自我创新和个性化网站设计的重视。

- 起因
- 使用标签作为关键词进行搜索
- 搜索后使用高亮标记关键词
- 近期的其他修改
  - 随机跳转文章
  - 给文章内标题添加锚链接
  - 添加能跳转到原始Markdown的链接
- 感想

看看其他的博客也会有新的灵感啊～

#
起因

前段时间，我闲来无事在GitHub上搜和我使用相同模板minimal的博客。但搜索结果中有许多人用这个模板制作的是简历或作品集，这让我有些失望。不过这倒也能理解，因为这个模版并不算博客模板，没有文章列表之类的代码，这些都只能自己写。当然多找找还是能找到一些的，毕竟这个模板在GitHub Pages中算是最受欢迎，至少符合大众的审美。像我就搜到了一个叫Guanzhou Hu的博客，他对模板的样式做了不少的改动，而且改的还挺好看的，尤其是右上角的导航栏，看起来挺有意思，只是这个源代码……导航栏有点硬编码的感觉，我不是很喜欢这种实现方式……

#
使用标签作为关键词进行搜索

之后我又看了看其他博客，看到了Matt Walker Blog。他没有对模板做很多改动，只是把section元素变得更宽了，但是他没有改手机版自适应的样式，导致界面基本上没法在手机上查看。不过在他的首页中，我对他把文章标签放在文章列表这个操作非常感兴趣，因为每次我都有给文章打标签，但是几乎没什么用。他的标签点进去之后会跳转到该标签下的所有文章，我其实很早就想做这个功能了，但是在不用插件的情况下Jekyll基本上做不出来这种功能，因为没有插件的情况下是不能使用Liquid标签创建文件的，我看了下他的实现，原来是提前创建好的标签页面然后进行筛选的，这个实现我也不喜欢，这样的话我每次打标签都要新建一个标签对应的页面，这种事情不让程序做我会很不爽……（其实现在的GitHub Pages构建网站都是用的Actions了，完全可以自己写一个可以使用插件的Actions来进行构建，不过我也懒得折腾了🤣）

要么还有一个选择，可以单独搞一个页面，里面有所有标签对应的文章，点击文章的标签之后使用锚链接定位到对应标签所在的位置。但这样会导致一个页面有可能有一堆相同的文章链接，结果这个页面比归档页面的链接还多，那就感觉有点糟糕了……

不过我想起来以前做的博客全文搜索功能，如果把标签作为关键词进行查询，那也能起到筛选出标签对应文章的作用吧？而且这样即使我没给那个文章打标签也能搜出来，其实也算不错的选择，另外自从我做出来那个全文搜索的功能之后也没用过几次，没有关键词的话也一时半会想不出来搜什么比较好。于是说做就做，直接把Matt Walker Blog那段在文章列表生成标签的代码复制过来，感觉好像还不错😆？

顺便我也把文章里面的标签也加了链接到搜索的功能，不过原来的代码用的是`.join`实现的，现在加上这个功能的话就只能老老实实用循环写了😥……

#
搜索后使用高亮标记关键词

上面的标签搜索效果还不错，只是有些关键词搜完之后有点难发现。我搜索出来之后怎么证明搜到的内容里面一定有对应的关键词呢？虽然从程序的角度来说这是理所应当的事情，一定是有的数据才可能被搜到，但有时候不用Ctrl+F看一眼都不知道是哪里搜到了……所以我觉得应该像其他网站一样对搜到的内容用高亮进行标记。标记应该用什么呢？用样式也许不错，不过现在的H5标签里有一个叫mark的标签可以直接用，用这个标签包裹的内容背景颜色就会变成黄色，就像用荧光笔标记了一样，这样就不需要写样式了。

至于关键词用查询字符串传过去就好了，那我该怎么做呢？我用的搜索脚本叫Simple-Jekyll-Search，它的文档其实根本没有写怎么把搜索的请求传到模版里，还好它有个关于模版的测试脚本里面有写，有个query关键词可以把搜索内容给模版渲染出来，既然做了这个功能怎么不写在文档里😅，不过这个项目已经停止，也没法提出什么建议了……

这个功能听起来相当简单，我都懒得写了，这种简单的功能直接让AI写才对！于是我把需求告诉它，让它给我实现一份，于是这就是让AI给我写的高亮关键词的JS代码（经过了一点修改）：

    $(function () {
        const urlParams = new URLSearchParams(window.location.search);
        const keyword = urlParams.get('kw')?.trim();

        if (!keyword) return;

        // 转义正则表达式特殊字符，避免安全问题
        const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        // 创建不区分大小写的正则表达式（全局匹配）
        const regex = new RegExp(`(${escapedKeyword})`, 'gi');

        // 递归遍历并高亮文本节点
        const escapeHTML = str => str.replace(/[&<>"']/g,
            tag => ({
                '&': '&amp;',
                '<': '&lt;',
                '>': '&gt;',
                '"': '&quot;',
                "'": '&#39;'
            }[tag] || tag));
        function highlightTextNodes(element) {
            $(element).contents().each(function () {
                if (this.nodeType === Node.TEXT_NODE) {
                    const $this = $(this);
                    const text = escapeHTML($this.text());

                    // 使用正则替换并保留原始大小写
                    if (regex.test(text)) {
                        const replaced = text.replace(regex, '<mark>$1</mark>');
                        $this.replaceWith(replaced);
                    }
                } else if (
                    this.nodeType === Node.ELEMENT_NODE &&
                    !$(this).is('script, style, noscript, textarea')
                ) {
                    highlightTextNodes(this);
                }
            });
        }

        $('section').each(function () {
            highlightTextNodes(this);
        });
    });

（2025.04.28更新：解决了一个潜在的解析问题）

我测试了一下，非常符合我的需求，各种情况都能按照我的预期工作，虽然说功能非常简单，但是能正常运行，AI写的还是挺不错的。

#
近期的其他修改

除了对搜索功能的优化，我还做了些别的功能：

##
随机跳转文章

前段时间我看到有其他人的博客增加了一个随机跳转文章的功能，不过他的博客是动态博客，实现也比较奇葩，是渲染页面时就已经决定好要随机的文章，也就是说无论用户想不想随便看看，程序都已经随机好了。当然用着静态博客的我来说，从原理上也做不到这一点，不过既然我之前在做相似文章推荐功能时已经对搜索功能的数据进行了缓存，那么直接用缓存的内容直接随机就好了吧……所以就随便写了写，代码也极其简单：

    <a href="javascript:getSearchJSON(function(data){window.location = data[Math.floor(Math.random()*data.length)].url})">Random</a>

##
给文章内标题添加锚链接

最近在修改我的博客的时候我更新了一下给文章生成目录的组件，在这时候我想看看它还有什么有意思的组件可以用，然后就发现了jekyll-anchor-headings，它可以像GitHub展示Markdown文件一样在标题上添加点击后就可以直接跳转到对应标题的锚链接，而且示例里也给出了怎么做可以像GitHub的风格。看起来挺有意思，所以就给自己加上了😆。

##
添加能跳转到原始Markdown的链接

在修改博客的时候我参考了一下Jekyll的官方文档，在这个时候发现了page.path这个变量。我想了一下这个变量可以用来链接到我的文章内容，然后就在文章标签位置的右侧加上了这个链接，为了能让它显示在右侧，我用的是`float: right`，但是这样会导致和文章标签不在同一行，查了一下才知道用了浮动就会强制将元素转换成块级元素，而文章标签用的是行内元素，所以对不齐，没办法就只能把这一整行都转换成块级元素了……于是代码如下：

    <span style="float: right;"><a href="{{ site.github.repository_url }}/tree/master/{{ page.path }}">查看原始文件</a></span>

#
感想

多看看其他人的博客看来也挺不错，可以看看其他人的想法，说不定就有可以参考的价值呢……不只是文章内容，网站本身的一些功能也是作者的想法啊……而对于那些只套别人模版，没什么自己的改动的博客，那就没什么意思了（当然不会代码的那就没办法了～）。有些人说博客中只有文章才是最重要的，但我觉得对于技术博客来说网站的代码也是展示自己的部分，所以折腾博客本身也是很重要的！

tags: 博客 - 搜索 - 优化 查看原始文件

#### 推荐文章

Loading...

上一篇：在UTM中使用苹果虚拟化的各种尝试
下一篇：如何使用JS通过订阅源查看文章？
想问这篇文章
召唤伊斯特瓦尔