☰
使用 data-* 属性与 dataset 读取元素自定义数据:get-user-attribute 实战详解
2026/10/7 20:14:32 网站建设 项目流程
  • 文档/教程
  • 前端

【免费下载链接】en.javascript.info

Modern JavaScript Tutorial

项目地址:https://gitcode.com/gh_mirrors/en/en.javascript.info
点击查看免费下载

本篇文章围绕 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中完全通用。

第二步:读取属性值(两种方式)

参考答案给出了两种等价读取方式:

方式代码适用场景
datasetelem.dataset.widgetName读取data-*前缀的自定义属性,最推荐
getAttributeelem.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

项目地址:https://gitcode.com/gh_mirrors/en/en.javascript.info
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询