空状态必须作为真实状态处理:需在DOM、样式、JS逻辑和辅助技术中统一实现,否则会导致屏幕阅读器不播报、键盘导航跳过、页面抖动等问题。

搜索无结果不是加个“没找到”就完事,关键得让这个状态在 DOM、样式、JS 逻辑和辅助技术里都成立——否则用户刷新后看到空白、键盘用户跳过区域、屏幕阅读器不播报、页面加载时抖动,全是因为空状态没被当做一个“真实状态”来对待。
为什么直接写里放“暂无结果”会出问题
常见错误是把提示硬编码进 HTML,比如在表格下方写一个 没找到匹配项,再用 JS show()/hide() 切换。这会导致:
-
display: none 后整个区域对屏幕阅读器不可见,用户根本不知道“这里本该有列表”
- JS 动态插入时若用
innerHTML = "" 清空再重写,可能触发 XSS(尤其拼接用户输入的关键词),且已绑定的事件监听器全丢失
- 空状态容器若没复用真实内容的 class(如
table-container),flex/grid 布局下高度突变、列错位、响应式断层
- 只靠灰色文字+小字号提示,不符合 WCAG 对比度要求,且无图标/语义支撑,对色觉障碍用户不友好
Layui 表格搜索后 emptyText 不显示?必须手动接管 done 回调
emptyText 只在初始渲染 data 为空时生效,搜索过滤后 res.data.length === 0,Layui 默认不触发它——这不是配置漏了,是设计如此。
- 在
table.render() 的 done 回调里判断:if (res.data && res.data.length === 0)
- 清空原
:用 $(".layui-table tbody").empty(),别用 .html("") 防止残留事件
- 插入自定义结构,例如:
未找到与 "xxx" 匹配的结果
- 确保该
所在的 仍保留在表格结构内,否则 colspan 失效、表头错位
怎么让“暂无结果”真正可感知、不闪、不跳
核心是三件事:结构复用 + 容器复用 + 无障碍播报。不是换内容,而是换状态。
- 空状态结构用
包裹,天然不渲染、不参与布局、不被读屏器扫描
- JS 检测到无结果时,用
document.getElementById("search-empty").content.cloneNode(true) 插入目标容器,避免 XSS 和事件丢失
- 空状态容器必须带
role="status" 和 aria-live="polite",例如:未找到相关结果
;切忌用 assertive,会打断用户当前语音
- 样式上复用真实内容容器的 class(如
list-container),仅通过 .list-container:has(:empty) 或 JS 添加 is-empty 类控制内部图标/文案,保证盒模型完全一致
最难的不是第一次显示“没结果”,而是用户改关键词、删输入框、切 Tab 再回来时,状态切换不闪、不抖、焦点不丢、读屏器不重复报——这些细节全靠 + cloneNode + aria-live + 容器复用四者咬合,缺一不可。
常见错误是把提示硬编码进 HTML,比如在表格下方写一个 ,再用 JS show()/hide() 切换。这会导致:
-
display: none后整个区域对屏幕阅读器不可见,用户根本不知道“这里本该有列表” - JS 动态插入时若用
innerHTML = ""清空再重写,可能触发 XSS(尤其拼接用户输入的关键词),且已绑定的事件监听器全丢失 - 空状态容器若没复用真实内容的 class(如
table-container),flex/grid 布局下高度突变、列错位、响应式断层 - 只靠灰色文字+小字号提示,不符合 WCAG 对比度要求,且无图标/语义支撑,对色觉障碍用户不友好
Layui 表格搜索后 emptyText 不显示?必须手动接管 done 回调
emptyText 只在初始渲染 data 为空时生效,搜索过滤后 res.data.length === 0,Layui 默认不触发它——这不是配置漏了,是设计如此。
- 在
table.render()的done回调里判断:if (res.data && res.data.length === 0) - 清空原
:用$(".layui-table tbody").empty(),别用.html("")防止残留事件- 插入自定义结构,例如:
未找到与 "xxx" 匹配的结果
- 确保该
所在的 仍保留在表格结构内,否则colspan失效、表头错位怎么让“暂无结果”真正可感知、不闪、不跳
核心是三件事:结构复用 + 容器复用 + 无障碍播报。不是换内容,而是换状态。
- 空状态结构用
包裹,天然不渲染、不参与布局、不被读屏器扫描 - JS 检测到无结果时,用
document.getElementById("search-empty").content.cloneNode(true)插入目标容器,避免 XSS 和事件丢失 - 空状态容器必须带
role="status"和aria-live="polite",例如:;切忌用未找到相关结果
assertive,会打断用户当前语音 - 样式上复用真实内容容器的 class(如
list-container),仅通过.list-container:has(:empty)或 JS 添加is-empty类控制内部图标/文案,保证盒模型完全一致
最难的不是第一次显示“没结果”,而是用户改关键词、删输入框、切 Tab 再回来时,状态切换不闪、不抖、焦点不丢、读屏器不重复报——这些细节全靠
+cloneNode+aria-live+ 容器复用四者咬合,缺一不可。 - 插入自定义结构,例如:
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











