必须用 article 包裹每条消息并设唯一 id,标题用 h3,时间戳用带时区的 time 元素,未读状态显式声明在 aria-label 中,操作按钮必须为 button 且带 data-msg-id,分页与时间处理须严格同步后端数据。

aria-label 必须显式声明未读状态,仅靠 CSS 类名变色或隐藏图标是无效的——屏幕阅读器读不出,刷新后状态丢失,后端也不认。
消息列表必须用 article 包裹每条消息
不用 div 堆叠,更不能套 ul/li。语义错误会直接导致:滚动定位偏移、键盘焦点跳过、屏幕阅读器无法识别为独立内容单元。
- 每条消息用
article标签,加唯一id="msg-123" - 标题用
h3,不是div class="title" - 时间戳必须是
time元素,且datetime属性带完整时区信息,如datetime="2026-05-26T10:15:22+08:00" - 未读状态写进
aria-label="未读:订单已发货",别只加class="unread"
button 是唯一合法的操作载体
“标记已读”“删除”“清空”这些动作,必须用 button type="button",不能用 span + click 模拟。
- 每个按钮必须带
data-msg-id="msg-456",批量操作时靠它收集 ID - 点击后先发请求(如
fetch('/api/messages/read', { method: 'POST', body: JSON.stringify({ id: 'msg-456' }) })),成功再更新 DOM 类名 - 禁用“点击即变色”式伪操作——后端没改状态,刷新就回退,等于白点
- 关闭面板前检查是否有 pending 请求,加
loading状态并禁用按钮
分页加载必须手动同步 total 和 active 状态
前端分页插件(比如 jQuery 的 page())只管 UI 渲染,不拉数据、不校验总数、不清状态。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
-
total参数必须从接口返回的真实值赋值,硬写死会导致第 N 页点不动 - 切换页码时,手动清除上一页所有
active类,否则多条高亮共存 - 页面刷新后,未读数不能依赖 JS 变量残留,要从
localStorage或接口重拉;若缓存,记得加时间戳校验是否过期 - 移动端点击热区太小?给
article加padding: 12px 16px,别只靠文字撑
时间格式和时区处理最容易翻车
后端传个 "1716718522"(UNIX 时间戳)或 "2026-05-26T10:15:22Z",前端直接 new Date().toString() 就完事?线上被投诉是分分钟的事。
- UNIX 时间戳要乘
1000再构造new Date(1716718522 * 1000) - ISO 字符串(含时区)可直接传给
new Date(),但显示时必须用toLocaleString()或Intl.DateTimeFormat()格式化 - 避免手写 “刚刚”“1 小时前” 这类文案——用户本地时区不同,发布时间可能变成“昨天”甚至“明天”
- 服务端返回的时间字段,如果没带时区,前端一律按 UTC 解析再转本地,不能默认当成东八区
真正卡住上线的,往往不是逻辑多复杂,而是某条 time 标签漏了 datetime 属性,或者某个 button 忘了加 data-msg-id —— 这些地方一漏,状态就断链,用户刷不出新消息、点不中已读按钮、清空后数据还在,全得返工。


















