DOM 特性(Attributes)与属性(Properties)完全指南:现代 JavaScript 教程中的同步机制与 dataset 实战

📅 发布时间:2026/10/8 7:49:51
DOM 特性(Attributes)与属性(Properties)完全指南:现代 JavaScript 教程中的同步机制与 dataset 实战
文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载当浏览器加载页面时它会解析HTML 并从中生成 DOM 对象对于元素节点大多数标准的 HTML 特性attributes会自动变成 DOM 对象的属性properties。然而特性与属性的映射并不是一一对应的——它们既有双向同步的默契也有特性单向影响属性的例外更有href返回完整 URL 这类属性值被浏览器加工过的陷阱。本篇以现代 JavaScript 教程zh.javascript.info的 DOM 特性与属性章节 为核心结合仓库中的配套练习与可运行示例系统讲清两者的区别、操作 API、同步规则以及用data-*特性安全传递自定义数据的最佳实践让你读完能够精准地在该用属性还是该用特性之间做出正确选择。先从概念上分清特性写在 HTML属性活在 DOM在 HTML 中标签可以拥有特性attribute当浏览器解析 HTML 文本并根据标签创建 DOM 对象时浏览器会辨别标准的特性并据此创建 DOM 属性property。例如如果标签是body idpage那么 DOM 对象就会有body.id page。但这条规则只对标准特性生效非标准的特性不会生成对应的 DOM 属性。来看一个直观的例子body idtest somethingnon-standard script alert(document.body.id); // test —— 标准特性 id 生成了属性 // 非标准的特性没有获得对应的属性 alert(document.body.something); // undefined /script /body注意一个元素的标准特性对于另一个元素可能是未知的。例如type是input对应HTMLInputElement类的标准特性但对body对应HTMLBodyElement类来说则不是——规范在相应元素类中详细描述了各自的标准属性。所以body idbody type... input idinput typetext script alert(input.type); // text alert(body.type); // undefinedDOM 属性没有被创建因为它不是一个标准的特性 /script /body在 DOM 节点类 中我们可以找到这种映射的类层次根源每个 DOM 节点都属于相应的内建类如HTMLInputElement、HTMLBodyElement、HTMLAnchorElement等而哪些特性是标准的、会生成哪种类型的属性正是由这些元素类定义的。简言之特性attribute——写在 HTML 中的内容属性property——DOM 对象中的内容。DOM 属性就是普通 JavaScript 对象DOM 节点本质上是常规的 JavaScript 对象因此我们可以像操作任何对象一样操作它们——这也是理解后续所有内容的前提。给 DOM 对象添加自定义属性document.body.myData { name: Caesar, title: Imperator }; alert(document.body.myData.title); // Imperator给 DOM 对象添加方法此时方法中的this就是该元素document.body.sayTagName function() { alert(this.tagName); }; document.body.sayTagName(); // BODY修改内建属性的原型为所有元素统一添加方法Element.prototype.sayHi function() { alert(Hello, Im ${this.tagName}); }; document.documentElement.sayHi(); // Hello, Im HTML document.body.sayHi(); // Hello, Im BODY所以DOM 属性和方法的行为与常规 JavaScript 对象完全一致它们可以承载任意类型的值它们的名字是大小写敏感的要写成elem.nodeType而不是elem.NoDeTyPe。HTML 特性四个 API 与一个集合既然非标准特性不会自动映射为 DOM 属性那如何访问它们所有特性都可以通过下面四个方法访问它们操作的实际上是 HTML 中的原始内容方法作用elem.hasAttribute(name)检查特性是否存在elem.getAttribute(name)获取特性值elem.setAttribute(name, value)设置特性值elem.removeAttribute(name)移除特性此外elem.attributes可以读取所有特性——它是属于内建Attr类的对象的集合每个对象具有name和value属性。读取非标准特性的示例body somethingnon-standard script alert(document.body.getAttribute(something)); // non-standard /script /bodyHTML 特性有两个重要特征它们的名字是大小写不敏感的id与ID相同它们的值总是字符串类型。下面是一个使用特性的扩展示例涵盖读取、写入、查看与遍历body div idelem aboutElephant/div script alert( elem.getAttribute(About) ); // (1) Elephant读取大写 A 也可以 elem.setAttribute(Test, 123); // (2) 写入数值会被转为字符串 123 alert( elem.outerHTML ); // (3) 所有特性包括刚设置的都在 HTML 中可见 for (let attr of elem.attributes) { // (4) 遍历所有特性 alert( ${attr.name} ${attr.value} ); } /script /body四个要点对应代码中的四个注释getAttribute(About)首字母大写也能读到值因为特性名大小写不敏感任何赋值给特性的内容最终都会变成字符串123被存为123所有特性包括我们设置的Test都会出现在outerHTML中attributes集合是可迭代对象包含元素全部特性标准与非标准以name/value形式存放。属性—特性同步哪些双向哪些单向当一个标准特性被改变对应的属性也会自动更新反之亦然——除了几个特例。双向同步的典型idinput script let input document.querySelector(input); // 特性 属性 input.setAttribute(id, id); alert(input.id); // id属性被更新了 // 属性 特性 input.id newId; alert(input.getAttribute(id)); // newId特性被更新了 /script单向同步的例外input.value只能从特性同步到属性反过来不行input script let input document.querySelector(input); // 特性 属性 input.setAttribute(value, text); alert(input.value); // text // 这个操作无效属性 特性 input.value newValue; alert(input.getAttribute(value)); // text没有被更新 /script这个单向特性在实际开发中非常有用用户输入会改变value属性比如用户在输入框中敲入了内容但 HTML 中的value特性仍然保留着原始值。因此当我们需要在用户操作之后恢复初始内容时直接从特性中读取即可。DOM 属性是多类型的布尔、对象与加工过的URLDOM 属性并不总是字符串。这与特性值永远是字符串形成鲜明对比。布尔型input.checkedinput idinput typecheckbox checked checkbox script alert(input.getAttribute(checked)); // 特性值是空字符串 alert(input.checked); // 属性值是true /script对象型style特性是字符串style属性是对象div iddiv stylecolor:red;font-size:120%Hello/div script alert(div.getAttribute(style)); // color:red;font-size:120%字符串 alert(div.style); // [object CSSStyleDeclaration]对象 alert(div.style.color); // red /script字符串但内容被加工href属性永远是完整 URL即使特性里写的是相对路径或#hashhrefDOM 属性也会返回完整的绝对 URLa ida href#hellolink/a script alert(a.getAttribute(href)); // #hello原始值 alert(a.href); // http://site.com/page#hello 形式的完整 URL /script这个差异在实战中极其关键——如果你需要与 HTML 中所写的完全一致的值必须使用getAttribute。仓库中 黄色链接练习的题解 就专门强调了这一点详见下文实战部分。非标准特性的价值与风险非标准、自定义的特性常被用来将自定义数据从 HTML 传递到 JavaScript或为 JavaScript标记HTML 元素。用法一作为数据标记驱动页面渲染!-- 标记这个 div 以在这显示 name -- div show-infoname/div !-- 标记这个 div 以在这显示 age -- div show-infoage/div script let user { name: Pete, age: 25 }; for (let div of document.querySelectorAll([show-info])) { let field div.getAttribute(show-info); // 读取标记名 div.innerHTML user[field]; // 首先 name 变为 Pete然后 age 变为 25 } /script用法二作为状态标记配合 CSS 选择器控制样式style /* 样式依赖于自定义特性 order-state */ .order[order-statenew] { color: green; } .order[order-statepending] { color: blue; } .order[order-statecanceled] { color: red; } /style div classorder order-statenewA new order./div div classorder order-statependingA pending order./div div classorder order-statecanceledA canceled order./div为什么用特性比用一堆样式类.order-state-new、.order-state-pending……更好因为状态切换只需一行赋值比删除旧类、添加新类简单得多div.setAttribute(order-state, canceled);风险在于如果我们出于自己的目的使用了非标准特性之后它被引入标准并有了自己的用途自定义属性就可能产生意料不到的副作用。HTML 语言在不断演进越来越多的特性进入标准。为了避免冲突规范提供了data-*特性——所有以data-开头的特性均被保留供程序员使用它们可以在dataset属性中访问。data-* 与 dataset传递自定义数据的合法安全方式所有以data-开头的特性均被保留供程序员使用。它们可在dataset属性中使用。如果elem有一个名为data-about的特性就可以通过elem.dataset.about读取body>style .order[data-order-statenew] { color: green; } .order[data-order-statepending] { color: blue; } .order[data-order-statecanceled] { color: red; } /style div idorder classorder>div>// 获取元素 let elem document.querySelector([data-widget-name]); // 读取值 alert(elem.dataset.widgetName); // menu // 或 alert(elem.getAttribute(data-widget-name)); // menu练习二将外部链接设为橙色importance 3任务描述 要求通过修改style属性把所有外部链接变成橙色。判定条件链接href中包含://但不是以http://internal.com开头。题解 给出了两种方案。方案一先用querySelectorAll(a)拿到所有链接再逐个过滤并特别强调必须用link.getAttribute(href)而不是link.href——因为我们需要的是 HTML 中的原始值而href属性返回的是加工后的完整 URLlet links document.querySelectorAll(a); for (let link of links) { let href link.getAttribute(href); // 原始值而非 link.href if (!href) continue; // 没有 href 特性 if (!href.includes(://)) continue; // 没有协议 if (href.startsWith(http://internal.com)) continue; // 内部链接 link.style.color orange; }方案二更简洁直接用 CSS 选择器完成筛选[href*://]匹配包含://的 href:not([href^http://internal.com])排除内部链接let selector a[href*://]:not([href^http://internal.com]); let links document.querySelectorAll(selector); links.forEach(link link.style.color orange);仓库中的可运行示例 source.view 与 solution.view 分别对应待完成版本与已解决版本后者完整展示了用 CSS 选择器方案实现的效果——http://google.com、ftp://ftp.com/my.zip、http://nodejs.org变橙而/tutorial.html、local/path无://和http://internal.com/test内部链接保持原样。总结什么时候用属性什么时候用特性属性property特性attribute类型任何值标准的属性具有规范中描述的类型字符串名字名字name是大小写敏感的名字name是大小写不敏感的操作特性的方法速查elem.hasAttribute(name)—— 检查是否存在这个特性elem.getAttribute(name)—— 获取这个特性值elem.setAttribute(name, value)—— 设置这个特性值elem.removeAttribute(name)—— 移除这个特性elem.attributes—— 所有特性的集合可迭代元素含name/value。在大多数情况下优先使用 DOM 属性。仅当 DOM 属性无法满足需求、且确实需要特性时才使用特性典型场景有两个需要非标准特性——但若它以data-开头应改用dataset需要读取 HTML 中所写的原始值——因为对应的 DOM 属性可能被浏览器加工过例如href属性始终返回完整 URL而getAttribute(href)才返回原文。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐Javacord斜杠命令(Slash Commands)实战现代Discord机器人交互Javacord斜杠命令 Slash Commands 实战现代Discord机器人交互 Javacord是一个简单易用的多线程Java库专为创建Disco一文读懂Taiwan-LLM-7B-v2.1-chat的训练超参数学习率5e-05如何影响模型表现一文读懂Taiwan LLM 7B v2.1 chat的训练超参数学习率5e 05如何影响模型表现 Taiwan LLM 7B v2.1 chat作为一款专为《现代 JavaScript 教程》实战DOM 子节点访问与导航属性全解析《现代 JavaScript 教程》实战DOM 子节点访问与导航属性全解析 本文以 en.javascript.info https://link.gitco文档/教程前端上一篇如何在Apple Silicon上快速部署mlx-community/DeepSeek-V4-Pro-Qwen3.5-4B-bf16零基础入门教程下一篇如何快速构建250格式的本地WebAssembly文件转换器VERT开源项目终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考