返回文章列表

原生 JavaScript 搜索与筛选笔记

示例文章

一个只有四篇文章的博客,不需要搜索服务也能提供好用的筛选。最重要的不是代码有多短,而是每一步都能单独解释:数据来自哪里,哪些条件生效,结果如何显示,以及脚本失败时读者还能做什么。下面是这个站点使用的思路。

先把文章当成数据

每篇文章登记标题、摘要、分类和标签。搜索只检查这些字段,正文继续留在 HTML 中。这样既不用下载所有文章才能开始搜索,也能让摘要成为真实的阅读线索。Home 的最近文章、Blog 的索引与文章头部需要同步,不能各自维护互相矛盾的日期。

让条件组合有明确含义

搜索前去掉首尾空白,将拉丁字母转成小写,再按空白拆成关键词。“JavaScript DOM”表示两个词都应匹配;分类是另一个同时成立的条件。切换分类保留关键词,删除关键词保留分类,“重置筛选”才清空两者。读者不需要猜按钮背后还做了什么。

const words = query.trim().toLowerCase().split(/\s+/).filter(Boolean);
const matches = posts.filter((post) => {
  const text = [post.title, post.summary, ...post.tags].join(' ').toLowerCase();
  return (category === 'all' || post.category === category)
    && words.every((word) => text.includes(word));
});

这段示例只说明匹配规则,不包含页面初始化与错误恢复。实际实现还要检查分类是否合法,以及数据是否准备好,才能切换读者看到的列表。

搜索流程:输入关键词与分类,按全部条件匹配,显示结果数量和文章列表
输入、匹配与显示分开,便于分别核对。

创建节点,不拼接用户输入

使用 createElement 创建标题和链接,用 textContent 放入文字。关键词只参与比较,不进入 HTML 字符串。文章地址来自站点登记的数据,并通过相对站点根路径解析;这让网站放在子目录时也能打开文章。页面初始化完成前,静态索引一直保留。

渐进增强的目标是:脚本成功时多一些便利,失败时仍然有文章可读。

给中文输入留出过程

中文输入法会经历拼音组合与选字。如果每个中间状态都立即刷新结果,会出现列表闪动和不必要的数量播报。组合输入期间先保留当前列表,组合结束后再匹配;普通输入仍即时更新。结果变化不移动焦点,读者可以继续输入。

值得单独检查的三种情况
操作应有结果
选择分类保留当前关键词
没有匹配说明原因并提供重置入口
脚本初始化失败继续显示静态文章索引

最后用失败场景检查设计

试一次多词搜索、一次未知分类、一次无结果,再禁用脚本刷新页面。还可以直接打开带 q 和 category 的网址,确认刷新后状态能恢复。小网站不必引入复杂框架,但这些简单检查能避免“演示时能用,换个入口就坏”的问题。

参考:DOM 标准中的 textContentUI Events 组合输入事件