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

搜索无结果不是加个“没找到”就完事,关键得让这个状态在 DOM、样式、JS 逻辑和辅助技术里都成立——否则用户刷新后看到空白、键盘用户跳过区域、屏幕阅读器不播报、页面加载时抖动,全是因为空状态没被当做一个“真实状态”来对待。
为什么直接写里放“暂无结果”会出问题
常见错误是把提示硬编码进 HTML,比如在表格下方写一个 <div class="empty">没找到匹配项</div>,再用 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)
- 清空原
<tbody>:用 <code>$(".layui-table tbody").empty(),别用 .html("") 防止残留事件
- 插入自定义结构,例如:
<tr><td colspan="5" class="layui-table-empty">
<i class="layui-icon"></i><p>未找到与 "xxx" 匹配的结果</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill10595" title="htmlppt.skill"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20d79f23518.jpg" alt="htmlppt.skill" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill10595" title="htmlppt.skill">htmlppt.skill</a>
<p>把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。</p>
</div>
<a href="/xiazai/skill10595" title="htmlppt.skill" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div>
<p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>
</td></tr>
- 确保该
<tr> 所在的 <code><tbody> 仍保留在表格结构内,否则 <code>colspan 失效、表头错位
怎么让“暂无结果”真正可感知、不闪、不跳
核心是三件事:结构复用 + 容器复用 + 无障碍播报。不是换内容,而是换状态。
- 空状态结构用
<template id="search-empty"></template> 包裹,天然不渲染、不参与布局、不被读屏器扫描
- JS 检测到无结果时,用
document.getElementById("search-empty").content.cloneNode(true) 插入目标容器,避免 XSS 和事件丢失
- 空状态容器必须带
role="status" 和 aria-live="polite",例如:<div role="status" aria-live="polite"><p>未找到相关结果</p></div>;切忌用 assertive,会打断用户当前语音
- 样式上复用真实内容容器的 class(如
list-container),仅通过 .list-container:has(:empty) 或 JS 添加 is-empty 类控制内部图标/文案,保证盒模型完全一致
最难的不是第一次显示“没结果”,而是用户改关键词、删输入框、切 Tab 再回来时,状态切换不闪、不抖、焦点不丢、读屏器不重复报——这些细节全靠 <template></template> + cloneNode + aria-live + 容器复用四者咬合,缺一不可。
常见错误是把提示硬编码进 HTML,比如在表格下方写一个 <div class="empty">没找到匹配项</div>,再用 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) - 清空原
<tbody>:用 <code>$(".layui-table tbody").empty(),别用.html("")防止残留事件 - 插入自定义结构,例如:
<tr><td colspan="5" class="layui-table-empty"> <i class="layui-icon"></i><p>未找到与 "xxx" 匹配的结果</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill10595" title="htmlppt.skill"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20d79f23518.jpg" alt="htmlppt.skill" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill10595" title="htmlppt.skill">htmlppt.skill</a> <p>把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。</p> </div> <a href="/xiazai/skill10595" title="htmlppt.skill" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p> </td></tr> - 确保该
<tr> 所在的 <code><tbody> 仍保留在表格结构内,否则 <code>colspan失效、表头错位怎么让“暂无结果”真正可感知、不闪、不跳
核心是三件事:结构复用 + 容器复用 + 无障碍播报。不是换内容,而是换状态。
- 空状态结构用
<template id="search-empty"></template>包裹,天然不渲染、不参与布局、不被读屏器扫描 - JS 检测到无结果时,用
document.getElementById("search-empty").content.cloneNode(true)插入目标容器,避免 XSS 和事件丢失 - 空状态容器必须带
role="status"和aria-live="polite",例如:<div role="status" aria-live="polite"><p>未找到相关结果</p></div>;切忌用assertive,会打断用户当前语音 - 样式上复用真实内容容器的 class(如
list-container),仅通过.list-container:has(:empty)或 JS 添加is-empty类控制内部图标/文案,保证盒模型完全一致
最难的不是第一次显示“没结果”,而是用户改关键词、删输入框、切 Tab 再回来时,状态切换不闪、不抖、焦点不丢、读屏器不重复报——这些细节全靠
<template></template>+cloneNode+aria-live+ 容器复用四者咬合,缺一不可。 - 空状态结构用


















