消息列表需用语义化html(如)替代div堆砌,按钮须为并带data-msg-id;未读状态以后端为准,localstorage仅缓存id等关键字段;分页需手动监听事件加载数据,时间显示须本地化处理。

消息列表 DOM 结构不能只用 div 堆砌
结构混乱会导致点击态丢失、滚动错位、屏幕阅读器无法识别。别用一堆嵌套 <div> 拼消息项,优先用语义化组合:
<ul>
<li>每条消息用 <code><article></article> 包裹,代表独立内容单元
<h3></h3>,时间戳放 <time datetime="2026-04-07T19:30">刚刚</time>,便于机器解析aria-label="未读:系统更新通知",而不是只靠 CSS 隐藏/变色<button></button>,且带 data-msg-id 属性未读状态必须靠后端同步,localStorage 只能缓存 UI 层
localStorage 存未读消息列表简单可靠,但它是前端副本,不是真相。服务端仍需维护真实未读状态,否则多端登录、页面刷新、离线操作都会翻车。
- 保存时只存关键字段:
id、title、time、read: false,不存大段正文或 base64 图片 - 读取时加兜底:
JSON.parse(window.localStorage.getItem('unreadMsgs') || '[]'),防止首次为null报错 - 用户点击某条消息,应先发请求到后端标记
msg_id为已读,成功后再更新localStorage并移除对应项 - 页面加载时,未读数应优先从接口拉取;若网络异常,再 fallback 到
localStorage的缓存值
分页加载必须手动处理数据与状态同步
你看到的 $("#page2").page({}) 是某款 jQuery 分页插件,它只管 UI 渲染,不拉数据。配置完就以为“自动加载”,是新手最常踩的坑。
- 必须监听
pageClicked和jumpClicked事件,在回调里调用 AJAX 获取对应页数据 -
total参数得从接口返回的真实总条数赋值,不能硬写死 —— 否则第 20 页之后点不动 - 切换页码时,记得清空上一页所有
.active类,否则多条消息同时高亮 - 移动端点击区域太小,建议给
<li>加padding: 12px 16px,别只依赖文字大小
时间格式和时区最容易被忽略
后端返回的时间字段如果是 UNIX 时间戳或 ISO 字符串,前端必须做本地化处理,否则用户看到的是 UTC 时间,和手机系统对不上。
- 推荐用
new Date(timestamp).toLocaleString()或Intl.DateTimeFormat,不要直接拼字符串 - 如果后端返回的是
"2026-04-07T19:30:00Z",用new Date()构造后调用.toLocaleTimeString()才能匹配用户本地时区 - 服务端也建议统一返回带时区信息的 ISO 格式,避免前端自行 guess 时区偏移











