热门标签应使用包裹列表,每个内含链接;禁用伪装容器,须防xss转义、支持键盘访问、history管理及焦点控制。

<mark></mark> 不是用来做热门搜索标签的,它只负责高亮已匹配的关键词;热门标签是独立数据展示逻辑,得靠 <ul></ul>/<li> 或 <div> + JavaScript 动态渲染。
<h3>热门标签该用什么 HTML 结构</h3>
<p>语义上没有专用标签,但必须避免用 <code><mark></mark> 或 <strong></strong> 伪装成标签容器。真实场景中:
- 用
<ul class="hot-tags"></ul>包裹一组<li>,每个<li>内放@#@#@#@#@#@#@#@#@#@0 - 若需点击后不跳转、仅触发 JS 搜索,
<a></a>的href设为"#"并加preventDefault(),否则会触发页面滚动 - 不要用
<span></span>平铺——无法表达“列表”语义,屏幕阅读器读不出项数和顺序 - 如果标签带删除按钮(如用户自定义),每个
<li>内补一个<button type="button" aria-label="删除 标签名">×</button>
动态插入热门标签时防 XSS 的关键操作
后端返回的标签名可能含 、<code>& 或脚本片段,直接 innerHTML = '<li>' + tag + '</li>' 等于开后门。
- 必须先对原始字符串做 HTML 实体转义:把
&→&,→ <code><,>→> - 再用
textContent设置文本内容,最后用insertAdjacentHTML('beforeend', '<li><a></a></li>')插入结构 - 别用
document.write()或eval()渲染——2026 年仍有人踩这个坑,尤其在旧 CMS 插件里 - 若用模板引擎(如 Handlebars),确认已开启自动转义;若用 React/Vue,
{tag}默认安全,但dangerouslySetInnerHTML或v-html仍需手动过滤
热门标签点击后怎么正确触发搜索
不能只改 URL 哈希或拼接 location.href,要兼顾可访问性与历史记录管理。
- 给每个
<a></a>加role="button"和tabindex="0",确保键盘可聚焦(尤其当它被 CSS 改成无下划线块状时) - 监听
click和keydown(Enter/Space),统一调用搜索函数 - 搜索动作发生后,用
history.pushState()更新地址栏,例如/search?q=前端,方便用户刷新或分享 - 别漏掉表单回退支持:监听
popstate,从 URL 参数还原标签状态并高亮对应<li>
最易被忽略的是焦点管理——用户点完一个热门标签,焦点应落在搜索结果区域(如 main 或 id="search-results"),否则键盘用户会卡在空白页。这不靠 CSS,得用 element.focus() 主动控制。











