☰
纯前端导航页开发实战:AI辅助打造免登录聚合入口
2026/9/26 1:12:13 网站建设 项目流程

1. 为什么我要折腾一个纯前端导航页

事情的起因特别简单。我平时要查资料、看论文、找一些辅助工具,浏览器书签栏早就塞满了,换台电脑或者用手机的时候又得重新找一遍。更麻烦的是,有些聚合入口页面加载慢、广告多,还动不动要登录。我就想,能不能自己做一个纯前端的导航页,打开就能用,不依赖后端,不存任何数据,换设备只要打开同一个 HTML 文件就行。

这个想法落地之后,我发现它其实是一个特别适合拿来练手 AI 辅助编程的小项目。整个页面就是一个 HTML 文件,里面塞了 CSS 和 JavaScript,双击就能在浏览器里跑起来。没有服务器、没有数据库、没有构建工具,甚至连 npm 都不用装。你把它丢到任何静态托管上,或者直接发给朋友,对方打开就能看到你整理好的导航内容。

我给它起的定位是“免登录聚合入口”——打开即用,不收集任何信息,所有链接和分类都写死在页面里,想改就改源码。核心关键词就四个:Yandex、AI、纯前端、导航页。Yandex 在这里的角色是搜索引擎入口之一,我会把它和其他常用搜索、工具站放在一起,方便一键跳转。AI 则是整个制作过程的加速器——我用 AI 帮我生成页面骨架、写样式、补交互逻辑,自己只做筛选和微调。

适合谁来参考?如果你有一点 HTML 基础,想做一个自己的浏览器起始页;或者你完全不懂代码,但愿意让 AI 帮你写,然后自己复制粘贴;再或者你是个前端新手,想找一个真实的小项目练手,这个导航页都挺合适。它不涉及任何后端逻辑,所以不用担心安全问题,也不用备案、不用买服务器。下面我就把整个思路、实现细节、踩过的坑,以及怎么用 AI 快速生成,完整地拆一遍。

2. 整体设计与技术选型思路

2.1 为什么坚持纯前端

纯前端的意思是这个页面所有的逻辑都在浏览器里跑,不需要向服务器请求数据。导航页这种场景天然适合纯前端,因为它的核心功能就是“展示链接”和“跳转”,没有任何需要服务端参与的地方。用户打开页面,浏览器解析 HTML、渲染样式、执行一点 JavaScript 做搜索过滤或者主题切换,完事。

我试过用后端渲染的方案,比如用 Node.js 起一个服务,每次请求动态生成页面。结果就是部署麻烦、维护成本高,而且一旦服务挂了页面就打不开。纯前端方案把这些问题全干掉了:一个 HTML 文件,复制到哪都能跑,断网也能打开(只要文件在本地),加载速度就是浏览器解析一个文件的速度。

还有一个很实际的原因:纯前端不需要登录。没有后端就没有用户系统,也就没有“登录才能用”这种破事。你打开就是全部功能,关掉不留痕迹。对于导航页这种工具属性极强的页面,这是最舒服的体验。

2.2 单文件结构 vs 多文件拆分

我一开始想的是把 HTML、CSS、JavaScript 拆成三个文件,看起来更“规范”。但实际用下来,单文件反而更合适。原因有三个:第一,分发方便,一个文件发给别人就行,不用打包压缩;第二,没有路径问题,不会出现 CSS 加载失败导致页面裸奔;第三,修改的时候不用在多个文件之间跳来跳去。

当然单文件也有缺点,就是文件会比较大,几千行堆在一起。但导航页的代码量其实很有限,我最后做出来大概 800 行左右,其中大部分是链接数据和样式。用编辑器折叠一下,维护起来完全没问题。如果你实在觉得长,可以用注释把区域划分清楚,比如“搜索区”“分类区”“样式区”“脚本区”。

2.3 数据写死还是动态加载

导航页的链接数据有两种存法:一种是直接写在 HTML 里,另一种是放在 JavaScript 数组里动态渲染。我选了后者。原因是动态渲染更方便做搜索过滤和分类折叠。如果链接直接写在 HTML 里,想加一个搜索框过滤就得用 DOM 操作去遍历节点,代码又臭又长。放在数组里,过滤就是对一个数组做 filter,然后重新渲染,逻辑清晰得多。

数据结构也很简单,就是一个对象数组,每个对象包含名称、链接、分类、描述这几个字段。分类用来分组,描述用来在鼠标悬停时显示提示。这个结构用 AI 生成特别快,你只要告诉它“给我生成一个包含 50 个常用工具链接的 JSON 数组,字段有 name、url、category、desc”,它几秒钟就吐出来了。

2.4 搜索功能的设计取舍

搜索框我做了两个用途:一是过滤当前页面的链接,二是直接跳转到 Yandex 搜索。怎么区分?我的做法是:输入内容后按回车,如果输入的是网址(包含点号或者 http),就直接跳转;否则就调用 Yandex 的搜索接口,把关键词拼到 URL 里跳过去。这样用户不用先选搜索引擎再输入,一个框搞定两件事。

这里有个细节:Yandex 的搜索 URL 格式是https://yandex.com/search/?text=关键词。关键词需要用encodeURIComponent编码,不然中文和特殊字符会出问题。这个编码步骤很多人会忘,导致搜索中文时链接断裂。我在代码里专门处理了这一步,后面会贴出来。

2.5 主题切换的必要性

导航页是每天都要打开的东西,白天和晚上光线不一样,固定一个配色肯定不舒服。我加了明暗两套主题,默认跟随系统,也可以手动切换。实现方式是用 CSS 变量定义颜色,切换的时候只改变量值,不用重写样式。这个方案的好处是切换瞬间完成,没有闪烁,而且新增颜色只要改变量定义就行。

主题切换的状态存在localStorage里,下次打开还记得你的选择。这里注意一点:localStorage是纯前端存储,不会上传到任何地方,清除浏览器数据就会重置。如果你不想留任何痕迹,可以把这段逻辑去掉,默认就用系统主题。

3. 核心细节解析与实操要点

3.1 页面骨架怎么搭

整个页面分三个区域:顶部搜索区、中间分类导航区、底部信息区。顶部放搜索框和主题切换按钮,中间按分类展示链接卡片,底部放一句说明和当前时间。布局用 Flexbox 和 Grid 混合,顶部用 Flex 做水平排列,中间用 Grid 做自适应卡片布局。

Grid 的列数我用的是repeat(auto-fill, minmax(200px, 1fr)),意思是每列最小 200px,能塞几列塞几列,剩余空间平均分配。这样在宽屏上显示四五列,在手机上自动变成一列,不用写媒体查询。这个技巧我强烈推荐,比手动断点简单多了。

卡片内部用 Flex 做垂直排列,名称在上,描述在下。描述文字用text-overflow: ellipsis做截断,防止长描述撑破卡片。悬停时卡片轻微上浮并加阴影,给一个视觉反馈。这些样式都不复杂,但组合起来体验就很顺。

3.2 链接数据的组织方式

数据我放在一个叫links的数组里,每个元素长这样:

{ name: "Yandex", url: "https://yandex.com", category: "搜索引擎", desc: "俄罗斯最大的搜索引擎,支持多语言搜索" }

分类我一开始分了七八个,后来精简到五个:搜索引擎、AI 工具、开发资源、效率工具、学习资料。分类太多反而找不到东西,五个刚好,每个分类下面十到二十个链接,一屏能看完。

这里有个经验:链接的desc字段不要写太长,控制在 20 个字以内。太长了卡片显示不全,鼠标悬停看提示又麻烦。我一般写一句最核心的说明,比如“支持多语言的搜索引擎”就够了。

3.3 搜索过滤的实现细节

搜索框的input事件触发过滤函数,函数里做三件事:拿到输入值、转小写、遍历links数组匹配name和desc字段。匹配用includes就行,不需要正则,简单可靠。匹配到的链接重新渲染到页面上,没匹配到的隐藏。

这里有个性能小技巧:不要每次输入都重新创建 DOM 节点,而是先创建好所有卡片,过滤的时候只切换display属性。这样输入的时候不会有卡顿,尤其是链接多的时候。我试过重新渲染的方案,输入快的时候会掉帧,改成切换显示之后就流畅了。

回车跳转的逻辑单独处理:判断输入值是否包含.或者http,如果是就当网址处理,直接window.location.href = 输入值;否则拼 Yandex 搜索链接。拼链接的时候记得编码:

const query = encodeURIComponent(inputValue); window.location.href = `https://yandex.com/search/?text=${query}`;

3.4 主题切换的变量方案

CSS 变量定义在:root里,明暗两套用[data-theme="dark"]覆盖:

:root { --bg: #ffffff; --text: #1a1a1a; --card-bg: #f5f5f5; } [data-theme="dark"] { --bg: #1a1a1a; --text: #e0e0e0; --card-bg: #2a2a2a; }

切换的时候改document.documentElement.dataset.theme的值,CSS 自动生效。存localStorage的键叫theme,值就是light或dark。页面加载时先读localStorage,没有就跟随系统:

const saved = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; const theme = saved || (prefersDark ? 'dark' : 'light'); document.documentElement.dataset.theme = theme;

这段代码放在<head>里,避免页面加载时闪白。我一开始放在</body>前面,结果暗色主题下打开会先闪一下白屏,体验很差。移到head里就解决了。

3.5 用 AI 生成代码的提示词技巧

我用 AI 生成这个页面的时候,提示词是分步给的,不是一次性让它写完整页面。第一步让它生成 HTML 骨架和 CSS 样式,第二步让它生成链接数据,第三步让它补搜索和主题切换的 JavaScript。分步的好处是每一步都能检查,错了容易改,不会一坨代码丢过来不知道从哪下手。

提示词里我会明确说“纯前端”“单文件”“不用任何框架”“不用外部 CDN”。这几个约束很重要,不然 AI 默认会给你引入 Bootstrap 或者 Tailwind,虽然好看但增加了依赖,违背了纯前端的初衷。如果你想要样式好看又不想引入框架,可以让 AI 用原生 CSS 写,它现在写得挺好的。

还有一个技巧:让 AI 生成代码的时候,要求它加注释。比如“每一段 JavaScript 都加中文注释说明用途”。这样你拿到代码之后能看懂,改起来也方便。我试过不加注释的版本,过两天自己都忘了哪段是干嘛的。

4. 完整实操流程与关键环节

4.1 从零开始搭建的步骤

第一步,新建一个文件叫index.html,用编辑器打开。第二步,把下面这段骨架复制进去:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>我的导航页</title> <style> /* 样式写这里 */ </style> </head> <body> <header> <input type="text" id="search" placeholder="搜索或输入网址..."> <button id="theme-toggle">切换主题</button> </header> <main id="nav"></main> <footer> <p>纯前端导航页 · 数据仅存本地</p> </footer> <script> /* 脚本写这里 */ </script> </body> </html>

第三步,把 CSS 变量和基础样式补上。第四步,定义links数组。第五步,写渲染函数和搜索逻辑。第六步,写主题切换。第七步,在浏览器里打开测试。

整个过程如果手动写,大概需要两三个小时。用 AI 辅助的话,半小时就能跑起来。我的做法是让 AI 生成初版,然后自己调样式和补充链接。AI 生成的代码不一定完全符合你的审美,但骨架和逻辑是对的,改起来比从零写快得多。

4.2 链接数据的批量生成

手动一个个填链接太慢了。我的做法是让 AI 生成一批,然后自己筛选。提示词可以这样写:“生成一个 JavaScript 数组,包含 30 个常用 AI 工具网站,每个元素有 name、url、category、desc 四个字段,category 统一为‘AI 工具’,desc 用一句中文说明用途。”

AI 会给你一个完整的数组,你复制到代码里就行。但要注意:AI 生成的 URL 可能不准确,尤其是比较新的网站。我一般会抽查几个,确认能打开。另外 AI 可能会编造一些不存在的网站,所以生成之后要自己过一遍,把打不开的删掉。

筛选的标准很简单:你平时真的会用。导航页不是链接收藏夹,不需要什么都放。我最后只留了 50 个左右的链接,每个都是高频使用的。链接太多反而找不到,少而精才是导航页的价值。

4.3 搜索框的交互打磨

搜索框的交互有几个细节值得打磨。第一,自动聚焦,页面加载后光标直接落在搜索框里,打开就能打字。第二,输入时实时过滤,不用按回车。第三,按回车时判断是搜索还是跳转。第四,按 Esc 清空输入并恢复全部链接。

自动聚焦用autofocus属性就行,但注意在移动端可能会自动弹出键盘,影响体验。我的做法是只在桌面端自动聚焦,移动端不聚焦。判断方式是用window.innerWidth或者matchMedia检测屏幕宽度。

实时过滤的防抖处理:如果链接很多,每次输入都过滤可能会卡。加一个 100 毫秒的防抖,输入停止后再过滤。不过我的链接只有 50 个,实测不防抖也不卡,所以就没加。如果你的链接超过 200 个,建议加上防抖。

4.4 响应式布局的适配

响应式主要靠 Grid 的auto-fill和minmax实现,前面说过了。但有几个地方需要额外处理:搜索框在窄屏上要占满宽度,主题切换按钮要缩小;卡片的内边距在手机上要减小;底部文字要居中。

我用的断点只有一个:max-width: 600px。小于 600px 的时候,搜索框宽度 100%,按钮只显示图标不显示文字,卡片内边距从 16px 减到 12px。这些调整用媒体查询写,几行代码就够了。

还有一个细节:viewport的meta标签一定要写,不然手机上会按桌面宽度渲染,字小得看不清。这个标签我见过很多人忘写,导致移动端体验极差。

4.5 部署与分发方式

纯前端页面的部署特别简单。方式一:直接把 HTML 文件发给别人,对方双击打开。方式二:丢到任何静态托管服务上,比如 GitHub Pages、Netlify、Vercel,拖拽上传就行,不需要配置。方式三:放在自己的服务器上,用 Nginx 指向文件目录。

我常用的是方式二,因为可以生成一个链接,手机和电脑都能访问。部署的时候注意一点:如果你的页面引用了外部资源(比如字体、图标),要确保这些资源也能访问,不然页面会缺样式。我的做法是不引用任何外部资源,图标用 Unicode 字符或者内联 SVG,字体用系统默认,这样部署到哪都不会出问题。

5. 常见问题与排查技巧实录

5.1 页面打开空白怎么办

最常见的原因是 JavaScript 报错导致渲染中断。排查方法:按 F12 打开开发者工具,看 Console 面板有没有红色报错。如果有,根据报错信息定位到具体行。常见错误包括:数组拼写错误、函数名写错、括号不匹配。

另一个原因是links数组为空或者格式不对。检查数组里每个元素是否有name和url字段,缺了会导致渲染函数报错。我建议在渲染函数开头加一个判断:如果数组为空,显示一句“暂无链接”,而不是直接报错。

还有一种情况是文件编码问题。如果 HTML 文件保存成了 GBK 编码,而meta标签写的是 UTF-8,中文会乱码。解决办法是用编辑器把文件另存为 UTF-8 编码。VS Code 右下角可以看和改编码。

5.2 搜索跳转链接不对

这个问题通常是编码没做。中文关键词直接拼到 URL 里,浏览器可能会截断或者乱码。一定要用encodeURIComponent处理。另外 Yandex 的搜索域名是yandex.com,如果你用的是其他区域域名,要相应替换。

还有一个坑:如果用户输入的内容本身就是一个完整 URL,比如https://example.com,你再用encodeURIComponent编码后拼到搜索链接里,就会变成搜索这个 URL 而不是跳转。所以要先判断是不是 URL,是的话直接跳转,不是才搜索。

判断逻辑可以这样写:

function isUrl(str) { return /^(https?:\/\/)?([\w-]+\.)+[\w-]+/.test(str); }

这个正则不完美,但够用。匹配到就跳转,匹配不到就搜索。

5.3 主题切换后刷新失效

原因是没存localStorage,或者存了但读取的时机不对。存的时候用localStorage.setItem('theme', theme),读的时候在head里同步读取。如果读取放在DOMContentLoaded事件里,页面会先渲染默认主题再切换,造成闪烁。

正确的做法是在head里写一段内联脚本,同步执行:

<script> (function() { const saved = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; document.documentElement.dataset.theme = saved || (prefersDark ? 'dark' : 'light'); })(); </script>

这段脚本要在 CSS 之前执行,这样样式应用的时候主题已经确定了。

5.4 移动端点击链接没反应

这个问题通常是因为卡片上的点击事件被其他元素挡住了。检查一下卡片的z-index和position属性,确保链接的a标签覆盖整个卡片区域。我的做法是把a标签设为display: block,宽高 100%,这样点击卡片任何位置都能跳转。

另一个原因是touch事件和click事件的冲突。如果你在卡片上绑定了touchstart又绑定了click,可能会触发两次。纯前端导航页一般不需要touch事件,用click就够了,浏览器会自动处理触摸。

5.5 常见问题速查表

问题现象可能原因排查方法解决方案
页面空白JS 报错F12 看 Console根据报错修代码
中文乱码文件编码不对看编辑器编码另存为 UTF-8
搜索乱码未编码检查 URL用 encodeURIComponent
主题闪烁读取时机晚看 head 脚本移到 head 同步执行
移动端点不动元素遮挡检查 z-index调整层级和点击区域
链接打不开URL 错误手动访问测试修正或删除链接
布局错乱Grid 不兼容看浏览器版本加 fallback 样式

5.6 我踩过的几个坑

第一个坑:一开始我把links数组写在了</body>前面的<script>里,结果渲染函数执行的时候数组还没定义,报错links is not defined。解决办法是把数组定义放在渲染函数调用之前,或者把渲染调用放在DOMContentLoaded事件里。

第二个坑:主题切换按钮的点击事件绑在了button上,但按钮里面有个span放图标,点击span的时候事件没触发。解决办法是用事件委托,绑在button上,然后判断event.target是不是按钮本身或者它的子元素。

第三个坑:搜索过滤的时候,我用innerHTML重新渲染整个列表,导致输入框失去焦点。因为innerHTML会替换整个main的内容,如果搜索框在main里面就会被替换掉。解决办法是把搜索框放在main外面,或者只更新卡片的display属性不重新渲染。

第四个坑:Yandex 的搜索链接在有些地区访问慢,我一开始以为是代码问题,后来发现是网络原因。这个没办法,只能接受。如果你主要用其他搜索引擎,可以把默认搜索换成别的,代码逻辑一样,改个 URL 就行。

6. 用 AI 加速开发的实际体验

6.1 AI 在哪些环节最省时间

对我来说,AI 最省时间的环节是写 CSS 样式和生成链接数据。CSS 样式虽然不难,但写起来琐碎,尤其是响应式调整和悬停效果,让 AI 生成初版然后自己微调,比从零写快很多。链接数据更是如此,手动收集 50 个网站的信息至少要半小时,AI 几秒钟就生成好了,我只需要筛选和验证。

JavaScript 逻辑 AI 也能写,但需要你描述清楚需求。比如“写一个函数,接收输入字符串,如果包含点号就跳转,否则拼 Yandex 搜索链接”,这种描述越具体,AI 生成的代码越准确。如果你只说“写个搜索功能”,它可能会给你一个很复杂的实现,反而不好用。

6.2 AI 生成代码的常见问题

AI 生成的代码有几个通病。第一,喜欢引入外部库,比如用 jQuery 做 DOM 操作,用 Moment.js 做时间格式化。这些库虽然方便,但增加了依赖,违背纯前端单文件的初衷。解决办法是在提示词里明确说“不用任何外部库”。

第二,代码风格不统一,有时候用var,有时候用const,有时候用箭头函数,有时候用function。这个不影响运行,但看起来乱。我的做法是生成之后自己统一一遍,或者让 AI 按指定风格重写。

第三,注释可能是英文的,或者干脆没注释。如果你需要中文注释,要在提示词里说清楚。我一般会要求“每段代码加中文注释,说明用途和注意事项”。

6.3 怎么让 AI 理解你的需求

让 AI 理解需求的关键是提供足够的上下文。不要只说“帮我写个导航页”,而要说“帮我写一个纯前端的导航页,单 HTML 文件,包含搜索框、分类链接卡片、明暗主题切换,不用任何外部库,样式用原生 CSS,数据存在 JavaScript 数组里”。

另外,分步提需求比一次性提完整需求效果好。先让 AI 生成骨架,再让它补样式,再让它加交互。每一步都检查一下,有问题及时纠正。如果一次性让它写完整页面,代码量太大,出了问题不好定位。

还有一个技巧:给 AI 看你想要的参考样式。比如你看到一个导航页觉得不错,可以把它的截图或者 HTML 结构描述给 AI,让它照着写。这样生成的代码更接近你的预期。

6.4 AI 辅助开发的边界

AI 能帮你写代码,但不能帮你做决策。比如分类怎么分、链接放哪些、配色用什么,这些需要你自己判断。AI 生成的方案是一个起点,不是终点。我见过有人直接把 AI 生成的页面拿来用,结果链接一半打不开,分类乱七八糟,体验很差。

另外,AI 生成的代码可能有安全漏洞,虽然纯前端导航页的风险很低,但如果你要处理用户输入(比如搜索框),还是要注意 XSS 攻击。我的做法是对用户输入不做任何 HTML 渲染,只用textContent设置文本,避免注入。

最后,AI 不能替代测试。生成的代码一定要在浏览器里实际跑一遍,点一点、搜一搜、切换主题看看,确认没问题再发布。我每次改完代码都会刷新页面测试,这个习惯帮我省了很多麻烦。

7. 后续可以怎么扩展

这个导航页的骨架已经能用了,但如果你想继续折腾,有几个方向可以扩展。第一个是加一个“常用”分类,把最常用的几个链接置顶,不用每次搜索。实现方式是在数据里加一个pinned字段,渲染的时候优先显示。

第二个是加键盘快捷键,比如按/聚焦搜索框,按1到5切换分类。这个用keydown事件监听就行,代码量不大,但用起来很顺手。

第三个是加导入导出功能,把链接数据存成 JSON 文件,换设备的时候导入。这个需要用到Blob和FileReader,稍微复杂一点,但也不难。导出就是把数组转成 JSON 字符串下载,导入就是读取文件解析成数组。

第四个是加一个简单的访问统计,用localStorage记录每个链接的点击次数,按次数排序。这个纯前端就能做,不需要后端。不过要注意localStorage有容量限制,别存太多数据。

我个人的体会是,导航页这种东西不需要一次做完美,先用起来,用着用着就知道哪里需要改。我第一版只有 20 个链接和一个搜索框,后来慢慢加到 50 个链接、加了主题切换、加了分类过滤。每次改动都很小,但积累起来体验就上来了。如果你也想做一个,建议先从最简单的版本开始,跑起来之后再迭代。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询