112、【Ubuntu】【Hugo】搭建私人博客:搜索功能(八)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Hugo】搭建私人博客:搜索功能(七)

分析了 onkeydown 的整体目标,以及有时 document.activeElement 可能不可靠的原因,下面继续

搭建私人博客

OK,总之 ae 获得了当前的焦点项,下面继续看不同 key 键的处理

首先,当 key 键为 Escape 时,重置搜索内容,清空输入框,清空结果,光标回到输入框

OK,接下来如果没有搜索结果,或者焦点不在搜索区域,就直接退出,防止在无关区域按方向键还能触发搜索导航

OK,接着是检测到

  • 首先是 e.preventDefault表示阻止默认滚动行为,因为 本身有滑动向下的功能,如果不组织默认行为,在键盘导航时,页面也滑动向下的话,体验就不好
  • 接着如果当前的焦点是在搜索框的话(ae == sInput),焦点就从输入框跳到第一个搜索结果(通过 activeToggle 实现焦点转移)

这里额外说下 resList.firstChild.lastChild,之前在 search.html 模板介绍过这个 HTML 结构如下,resList<ul> 搜索结果集合,firstChild<ul> 搜索结果中的第一个 <li> 列表项,而 lastChild<li> 列表项里最后一个元素 <a href ...>,也就是搜索结果链接

  • 最后如果当前的焦点不是搜索框,而是搜索结果中的某一项(但不是最后一项,ae.parentElement != last),此时就通过 activeToggle 将焦点向下移动到下一个列表项 <li> 中的 <a href> 搜索结果链接

同样这里的 ae.parentElement.nextSibling.last 也展示了焦点的转移过程:当前 <a href> -> 父元素 <li> -> 下一个 <li> -> 它的 <a href>

OK,接下来是检测到

和前面的 键有点类似,逻辑对称,首先 e.preventDefault 同样表示阻止默认滚动行为,然后如果已经在第一项的话,就回到搜索输入框,或者向上移动到上一个结果

OK,下面看最后一个

这里的 ae.click 表示触发点击事件,跳转页面,用来模拟鼠标点击当前高亮的链接,此时用户按下 键,就像点击了一下,非常直观,当然,这里除了 键,直接按 Enter 键也是可以跳转的,没问题

OK,下面再回过头看下 activeToggle 的功能

其核心目的是高亮(视觉聚焦)某一个搜索结果项,并清除其他项的高亮状态,用于上面介绍的键盘导航(比如按 或者 键来选中下一项)

首先是

javascript 复制代码
document.querySelectorAll('.focus').forEach(function (element) {
    element.classList.remove("focus")
});

这里会找到页面上所有带 class="focus" 的元素(一般是 <li> 列表项),然后把它们的 focus 类全部移除,清除所有已有的高亮状态,确保同一时间只有一个结果被高亮,比如

OK,接下来判断是否传入了要激活的元素 ae

javascript 复制代码
if (ae) {
    ae.focus()
    document.activeElement = current_elem = ae;
    ae.parentElement.classList.add("focus")
}
  • ae.focus 会让这个元素(这里是 <a href ...> 可跳转链接)获得键盘焦点,然后用户按下 Enter 或者 键就能触发跳转

另外,这里有点小问题,document.activeElement 是只读属性,不应该被赋值

所以这里的实际效果是把 ae 赋值给全局变量 current_elem(供后续导航使用),用于记录当前选中项,但 document.activeElement = ae 完全无效,会被浏览器忽略

  • ae.parentElement.classList.add("focus"):这里给 <a href ...> 的父元素,也就是 <li> 列表项加上 focus 类,会触发 CSS 高亮效果,比如边框,缩放等特殊效果

OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Hugo】搭建私人博客:搜索样式(一)

相关推荐
cooldream20093 小时前
Vim 报错 E325:swap 文件冲突的原理、处理流程与彻底避免方案
linux·编辑器·vim
i建模3 小时前
在 Rocky Linux 上安装轻量级的 XFCE 桌面
linux·运维·服务器
Data_Journal3 小时前
Scrapy vs. Crawlee —— 哪个更好?!
运维·人工智能·爬虫·媒体·社媒营销
若风的雨3 小时前
WC (Write-Combining) 内存类型优化原理
linux
YMWM_3 小时前
不同局域网下登录ubuntu主机
linux·运维·ubuntu
zmjjdank1ng3 小时前
restart与reload的区别
linux·运维
哼?~4 小时前
进程替换与自主Shell
linux
Suchadar4 小时前
Docker常用命令
运维·docker·容器
你才是臭弟弟4 小时前
MinIo开发环境配置方案(Docker版本)
运维·docker·容器
Bruk.Liu4 小时前
Gitea Actions 的概念及基础使用
运维·ci/cd·持续集成