
怎么用 data-* 属性实现维度切换而不刷新页面
靠 location.hash 或 URL 参数做切换最省事,但容易和路由冲突;用 data- 属性配合 JS 控制更轻量、更可控。关键是把维度状态存在元素上,而不是靠 DOM 位置或 class 名硬编码。
-
data-dimension="time"、data-dimension="type"、data-dimension="hot"统一作为触发器的识别依据 - 点击按钮时只改
data-active-dimension在容器上的值,不删增 class,避免样式抖动 - 渲染逻辑全由 JS 驱动:读取当前
data-active-dimension,再过滤/排序data-item元素,最后用documentFragment批量重排,比逐个appendChild快得多 - 别在
click里直接调innerHTML = ...—— 会清空绑定的事件监听器,导致后续切换失效
HTML 结构怎么写才方便 JS 拿到原始数据
作品项不能只靠视觉分类,得自带结构化元信息。否则切“热度”时还得去请求接口,失去本地切换意义。
- 每个作品
<article>必须带data-time(ISO 格式)、data-type(如"illustration")、data-hot(数字,不是文字“高”“中”) -
data-hot建议存归一化值(0–100),避免后端返回 “12.5k” 这类字符串,JS 排序会出错 - 不要用
title或alt存维度数据 —— 它们语义不对,且可能被压缩、转义,读取不可靠 - 示例:
<article data-time="2023-08-15" data-type="ui" data-hot="87">...
为什么 sort() 按时间排老是出错
常见错误是直接对 NodeList 调 sort() —— 它不是数组,没有该方法;或者把 data-time 当字符串比,结果 "2023-1-5" > "2023-10-1" 返回 true。
- 先用
[...document.querySelectorAll('[data-item]')]转成真数组 - 时间排序必须转
Date对象:a => new Date(a.dataset.time),别用localeCompare - 热度和类型排序要预处理:类型用对象映射优先级(
{ ui: 0, illustration: 1, animation: 2 }),热度直接转Number() - 注意
dataset取值是字符串,Number('')是 0,new Date('')是 Invalid Date —— 得加兜底判断
切换动画卡顿?检查这三处 DOM 操作
看似只是换顺序,但频繁重排重绘会让 60fps 掉到 20fps,尤其作品超过 30 个时。
立即学习“前端免费学习笔记(深入)”;
- 别在循环里反复读
offsetHeight或getComputedStyle—— 强制同步布局,浏览器缓存失效 - 所有插入操作集中到一个
DocumentFragment,最后一次性append()到容器 - 用
transform: translateY()做淡入/滑入,别用opacity+height—— 后者触发布局计算 - 如果用 CSS 过渡,确保切换前给容器加
will-change: transform,但别滥用,只在激活切换时设
实际项目里最容易被忽略的是数据一致性:比如后台改了某作品的 data-time,但前端缓存了旧 NodeList,下次切换就排错。要么每次切换都重新查 DOM,要么用 MutationObserver 监听变化 —— 后者成本高,小项目直接重查更稳。











