- 文档/教程
- 前端
【免费下载链接】en.javascript.info
Modern JavaScript Tutorial
本篇文章围绕 javascript.info 教程中"获取自定义属性(Get the attribute)"这一经典练习展开,演示如何通过属性选择器选中带有data-widget-name的元素,并分别用elem.dataset.widgetName与elem.getAttribute('data-widget-name')读取其值。读完本文,你将掌握 DOM 属性(property)与 HTML 属性(attribute)的本质区别、四个属性操作 API、data-*自定义数据的正确打开方式,以及何时该用getAttribute而非直接访问 DOM 属性。
任务背景:从 HTML 中提取组件自定义数据
该练习出自 2-ui/1-document/06-dom-attributes-and-properties 章节,属于 DOM 属性与 HTML 属性专题下的第一道动手题。题目要求(见 task.md)非常简单直白:
编写代码,从文档中选中带有
data-widget-name属性的元素,并读取它的值。
给定的起始 HTML 如下:
<!DOCTYPE html> <html> <body> <div><!DOCTYPE html> <html> <body> <div>document.querySelectorAll('[data-widget-name]').forEach(elem => { console.log(elem.dataset.widgetName); });属性选择器还可以做更精确的匹配,例如[data-widget-name="menu"]只匹配值恰为"menu"的元素,[data-widget-name^="m"]匹配值以"m"开头的元素。这些语法在 CSS 与querySelector/querySelectorAll中完全通用。
第二步:读取属性值(两种方式)
参考答案给出了两种等价读取方式:
| 方式 | 代码 | 适用场景 |
|---|---|---|
| dataset | elem.dataset.widgetName | 读取data-*前缀的自定义属性,最推荐 |
| getAttribute | elem.getAttribute('data-widget-name') | 读取任意属性(含非data-*属性)的原始字符串值 |
elem.dataset.widgetName走的是dataset属性——所有data-*属性都会被浏览器自动收集进elem.dataset对象,属性名去掉data-前缀,连字符写法自动转为小驼峰(data-widget-name→widgetName)。elem.getAttribute('data-widget-name')则是通用属性 API,传入完整属性名,返回 HTML 中"原样书写"的字符串值。
深入原理:DOM 属性与 HTML 属性的区别
为什么同一份数据会有dataset和getAttribute两种读法?因为浏览器解析 HTML 时,对元素节点做了两套记录:
- HTML 属性(attribute):HTML 源码中写的东西,例如
<div><body id="test" something="non-standard"> <script> alert(document.body.id); // test // non-standard attribute does not yield a property alert(document.body.something); // undefined </script> </body>两者的核心差异可以总结为下表:
维度 DOM 属性(Properties) HTML 属性(Attributes) 本质 DOM 对象上的 JavaScript 属性 HTML 中书写的内容 类型 任意值(标准属性有规范定义的类型) 永远是字符串 名称 区分大小写 不区分大小写 由于属性名不区分大小写,
getAttribute('About')与getAttribute('about')效果相同;而属性值永远被转成字符串,例如setAttribute('Test', 123)会把数值123存储为字符串"123"。完整的属性操作 API
任务只涉及读取,但实际开发中常配套使用其余三个 API。它们是操作 HTML 属性的四个基本方法:
方法 作用 elem.hasAttribute(name)检查元素是否拥有该属性 elem.getAttribute(name)获取属性值(字符串) elem.setAttribute(name, value)设置属性值 elem.removeAttribute(name)移除属性 此外,
elem.attributes是一个可迭代集合,包含元素上所有属性(标准的和非标准的),每个元素是Attr对象,带name和value属性:for (let attr of elem.attributes) { console.log(`${attr.name} = ${attr.value}`); }属性与 DOM 属性的同步机制
对标准属性,两者通常自动双向同步:修改
id属性,elem.id属性随之更新;反向亦然。但有例外——input.value只同步"属性 → 属性",反向不成立:<input> <script> let input = document.querySelector('input'); input.setAttribute('value', 'text'); alert(input.value); // text(属性同步到了 property) input.value = 'newValue'; alert(input.getAttribute('value')); // text(property 没有同步回 attribute) </script>这正是"读原始值用
getAttribute"这一建议的根源:用户操作会改变value等 DOM 属性,而 HTML 中"原本写的是什么"仍保存在属性里。同理,href的 DOM 属性永远是完整解析后的 URL(即使源码里只写了#hello,a.href也会是http://site.com/page#hello),要拿到"原样书写"的值必须用a.getAttribute('href')。这道题的姊妹练习 Make external links orange 正是利用了这一区别:判断外链时使用link.getAttribute('href')而非link.href,因为需要的是 HTML 中的原始值。为什么推荐><style> .order[data-order-state="new"] { color: green; } .order[data-order-state="pending"] { color: blue; } .order[data-order-state="canceled"] { color: red; } </style> <div id="order" class="order">赞
- 文档/教程
- 前端
【免费下载链接】en.javascript.info
Modern JavaScript Tutorial
相关推荐
从 DOM 读取>从 DOM 读取 data widget name 自定义属性:getAttribute 与 dataset 完整指南 在现代 JavaScript 教程(Mo
文档/教程前端FASTElementDefinition.attributes 属性详解:@microsoft/fast-element 自定义元素属性元数据的内幕
FASTElementDefinition.attributes 属性详解:@microsoft/fast element 自定义元素属性元数据的内幕 导读 F
前端UI组件terraform-provider-aws 数据源详解:使用 aws_bedrock_custom_model 读取 Amazon Bedrock 自定义模型属性
terraform provider aws 数据源详解:使用 aws_bedrock_custom_model 读取 Amazon Bedrock 自定义模型
IaC云原生基础设施