Element.getAttributeNames()返回一个字符串数组,包含元素显式设置的所有属性名,如id、class及data-开头的自定义属性,但不包括JS动态添加的属性。

Element.getAttributeNames 返回的是什么
Element.getAttributeNames() 返回一个字符串数组,只包含该元素显式设置的**所有属性名**(包括标准属性如 id、class,也包括自定义属性如 data-id、my-flag),但不包括通过 JavaScript 动态添加但未写入 HTML 的属性(比如 el.myProp = 'x' 不会出现在结果里)。
它不区分“标准”还是“自定义”,只是把 DOM 中真实存在的 attribute 名字列出来。所以想筛出自定义属性,得靠你自己过滤。
怎么准确识别并提取自定义属性
浏览器没有内置“自定义属性”的类型标记,通用做法是按命名约定判断:以 data- 开头的属性(HTML5 规范允许)或全小写、不含连字符但又非标准属性的名字(如 foo、bar)。但后者风险高——你无法 100% 确认它是不是某个框架私有属性(比如 _vnode)。
实际项目中,最稳妥且符合规范的做法是只认 data- 前缀:
立即学习“前端免费学习笔记(深入)”;
- 用
getAttributeNames()拿到全部属性名 - 用
.filter(name => name.startsWith('data-'))筛出标准自定义属性 - 避免用
hasAttribute('data-*')之类模糊匹配——通配符不被支持
示例:
const editor = document.querySelector('#my-editor');
const allAttrs = editor.getAttributeNames(); // ['id', 'contenteditable', 'data-theme', 'data-autosave', 'class']
const customDataAttrs = allAttrs.filter(n => n.startsWith('data-')); // ['data-theme', 'data-autosave']
为什么 getAttributeNames 在富文本编辑器节点上可能返回空或不全
常见于基于 contenteditable 的编辑器(如 Quill、Slate、或者手写的 div 编辑器),问题往往不在 API 本身,而在节点状态:
- 你取的不是最外层容器节点,而是内部临时生成的
span或div——它们可能没挂自定义属性 - 编辑器在初始化时清除了原始 HTML 上的属性,或用 JS 重写了
outerHTML - 某些编辑器(如 TinyMCE)把配置存在 JS 对象里,根本不写进 DOM attribute
- Shadow DOM 场景下,若编辑器用了
attachShadow,而你在 shadow 外调用getAttributeNames,自然拿不到影子树内的属性
验证方法:直接在控制台执行 editor.outerHTML,看你要的 data- 属性是否真存在于 HTML 字符串中。
兼容性与性能注意点
getAttributeNames 是较新的 API(Chrome 61+、Firefox 62+、Edge 79+),IE 完全不支持。如果要兼容老环境,得回退到 element.attributes(返回 NamedNodeMap):
const attrs = Array.from(element.attributes).map(attr => attr.name);
性能上无需担心:getAttributeNames() 内部就是遍历 attributes,两者开销基本一致。但注意:频繁调用(比如在输入事件里)仍建议缓存结果,尤其当节点结构复杂时。
真正容易被忽略的是:自定义属性值如果是 JSON 字符串(如 data-config='{"mode":"lite"}'),必须用 JSON.parse(el.getAttribute('data-config')) 解析,不能依赖 getAttributeNames 帮你做这事——它只管名字,不管值。


















