data-*属性须全小写、短横线分隔,如data-user-id;queryselector精确匹配需加引号,如[data-tag="vue"];dataset自动转换值且不支持点号,ie11需回退getattribute。

data-* 属性怎么写才有效
HTML 的 data-* 属性必须全小写、用短横线分隔,且不能包含大写字母或下划线。浏览器会自动把带短横线的 data- 属性转成驼峰形式供 JS 读取,但写的时候不按规范,dataset 就拿不到值。
-
data-category="js"✅ 可用el.dataset.category读取 -
data-categoryName="js"❌ 不合法,会被忽略(HTML 规范只认短横线分隔) -
data-category_name="js"❌ 下划线不被支持 -
data-CATEGORY="js"❌ 大写字母会导致解析失败
常见错误是复制后端模板变量名直接塞进 data-,比如 data-userId,实际得写成 data-user-id,否则 dataset.userId 是 undefined。
querySelector 怎么精准匹配 data 属性值
别用 querySelector('[data-type=react]') 这种裸等号写法——它不支持空格、引号、特殊字符,而且会把 react-native 也匹配进来。真要精确筛选,必须加引号并用属性选择器语法。
- 匹配完全相等:
document.querySelectorAll('[data-tag="vue"]') - 匹配包含某个词(空格分隔):
document.querySelectorAll('[data-tags~="typescript"]')(注意是~,不是=) - 匹配以某值开头:
document.querySelectorAll('[data-role^="admin"]') - 避免漏掉空格或大小写问题:后端吐出的
data-status=" pending "带前后空格,直接="pending"就失效
如果值来自用户输入或不可控来源,建议先 trim 后再设到 DOM 上,或者改用 JS 端遍历 + dataset 判断,更可控。
dataset 和 getAttribute 有什么区别
dataset 是快捷读取通道,但会做自动转换;getAttribute 是原始字符串,一字不差。选哪个取决于你是否信任数据格式和是否需要原始值。
-
el.dataset.count把data-count="0123"转成字符串"0123",但data-count="1e2"会变成"100"(被当成数字解析再转回字符串) -
el.getAttribute('data-count')拿到的就是原样"1e2",不会二次解析 -
dataset不支持带点或冒号的 key,比如data-api-url→dataset.apiUrl,但data-api.version会直接被忽略(点号非法) - IE11 不支持
dataset,老项目需 fallback 到getAttribute
做筛选逻辑时,如果 value 是纯字母数字,用 dataset 更快;如果含符号、前导零、科学计数法,或要兼容 IE,就老实用 getAttribute。
JS 筛选性能要注意什么
每次调用 querySelectorAll 都触发重排(reflow),尤其在循环里反复查同一批元素,性能掉得很快。真实场景中,筛选往往伴随显示/隐藏,别让 DOM 操作和查询混在一起瞎跑。
- 先用
document.querySelectorAll('[data-tag]')拿到全部候选节点,缓存为数组,后续筛选都在这个数组里filter() - 避免在
for循环里反复写el.dataset.tag === 'xxx',改成Array.from(els).filter(el => el.dataset.tag === 'xxx')更易读且 V8 优化更好 - 如果筛选条件变多(比如同时按
tag和status),别堆嵌套querySelector,用一次获取 + 多字段判断更稳 - 注意
dataset返回的是 DOMStringMap,不是普通对象,不能用Object.keys()直接遍历键名
最常被忽略的是:筛选后批量操作 DOM 时,没用 DocumentFragment 或 display: none 临时隐藏父容器,导致每改一个子元素都触发一次样式计算——这点比 data 属性写法本身影响更大。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











