ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

《现代 JavaScript 教程》DOM 特性(attribute)与属性(property)实战:从 data-* 自定义数据到 dataset 读取

《现代 JavaScript 教程》DOM 特性(attribute)与属性(property)实战:从 data-* 自定义数据到 dataset 读取 文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载本文基于《现代 JavaScript 教程》中文仓库 2-ui/1-document/06-dom-attributes-and-properties/article.md 及其配套练习任务编写。当浏览器解析 HTML 生成 DOM 时标准 HTML 特性会自动变成 DOM 属性但这两者并非一一对应。读完本文你将掌握特性与属性的本质区别、完整的特性操作 API、data-*自定义数据的安全传递方式dataset并能够独立完成获取data-widget-name特性值与将外部链接染成橙色两类典型实战任务。一、两个易混淆的概念特性attribute与属性property在继续之前先建立最基础的心智模型特性attribute——写在 HTML 标签里的内容例如body idpage中的idpage。属性property——DOM 对象上的 JavaScript 属性例如解析后生成的document.body.id。当浏览器加载页面时它会解析 HTML 并生成 DOM 对象。对于元素节点大多数标准的 HTML 特性会自动变成 DOM 对象的属性。例如标签body idpage会让 DOM 对象拥有body.id page。但要注意特性—属性映射并不是一一对应的。本章节接下来的内容全部围绕它们何时相同、何时不同、如何操作展开。二、DOM 属性本质是常规 JavaScript 对象DOM 节点是常规的 JavaScript 对象因此我们可以像操作任何对象一样自由扩展它——没有任何技术限制。例如给document.body挂载自定义数据document.body.myData { name: Caesar, title: Imperator }; alert(document.body.myData.title); // Imperator也可以添加方法document.body.sayTagName function() { alert(this.tagName); }; document.body.sayTagName(); // BODY方法中的 this 指向 document.body甚至可以修改内建原型为所有元素统一注入新方法Element.prototype.sayHi function() { alert(Hello, Im ${this.tagName}); }; document.documentElement.sayHi(); // Hello, Im HTML document.body.sayHi(); // Hello, Im BODY由此可以总结出 DOM 属性的两条行为准则属性可以承载任意类型的值对象、函数、布尔值等属性名是大小写敏感的必须写elem.nodeType不能写elem.NoDeTyPe。三、HTML 特性标准与非标准之分浏览器解析 HTML 文本并创建 DOM 对象时只会为标准特性创建对应的 DOM 属性非标准特性不会。看下面这个例子body idtest somethingnon-standard script alert(document.body.id); // test // 非标准的特性没有获得对应的属性 alert(document.body.something); // undefined /script /body进一步说标准是相对元素类型而言的type对inputHTMLInputElement是标准特性对bodyHTMLBodyElement则不是body idbody type... input idinput typetext script alert(input.type); // text // 没有对应的 DOM 属性因为它不是 body 的标准特性 alert(body.type); // undefined /script /body那么既然非标准特性没有对应的 DOM 属性我们该如何访问它答案是使用下面这一组特性操作 API。四、特性操作四大方法 attributes 集合所有特性无论标准与否都可以通过以下方法访问这些方法操作的实际是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首字母大写也能读取 elem.setAttribute(Test, 123); // (2) 写入值会被转成字符串 123 alert( elem.outerHTML ); // (3) 新特性在 outerHTML 中可见 for (let attr of elem.attributes) { // (4) attributes 可迭代列出全部 alert( ${attr.name} ${attr.value} ); } /script /body四个值得注意的细节getAttribute(About)首字母大写照样能读到因为特性名大小写不敏感任何值赋给特性都会被字符串化所以写入123实际存储的是123所有特性包括我们刚设置的都会出现在outerHTML中attributes是可迭代对象能用for...of遍历其中包含标准与非标准的所有特性。五、属性—特性同步及value例外当一个标准特性被改变时对应的 DOM 属性会自动更新反过来属性被赋值时特性也会同步——只有少数特例。看双向同步的演示input 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 中的原始值始终保存在特性里——需要恢复初始值时从getAttribute(value)取即可。六、DOM 属性是多类型的checked、style 与 hrefDOM 属性不总是字符串input.checkedcheckbox是布尔型input idinput typecheckbox checked checkbox script alert(input.getAttribute(checked)); // 特性值是空字符串 alert(input.checked); // 属性值是true /scriptstyle特性是字符串style属性是对象CSSStyleDeclarationdiv 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哪怕特性里写的是相对路径或#hasha ida href#hellolink/a script alert(a.getAttribute(href)); // #helloHTML 中的原始写法 alert(a.href ); // http://site.com/page#hello 形式的完整 URL /script因此当我们需要HTML 中写的原样值时必须使用getAttribute——这一结论将直接服务于后面的实战任务。七、非标准特性与>!-- 标记这个 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自定义特性还可以驱动样式例如用order-state控制订单状态的颜色style .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 标准在持续演进你今天用的非标准特性可能明天就被标准收编、赋予新含义从而产生意料之外的影响。为了避免冲突HTML 规范保留了data-*前缀所有以data-开头的特性均被保留供程序员使用它们可以通过dataset属性访问。命名规则很简单data-about特性对应elem.dataset.about多词特性如data-order-state以驼峰式访问elem.dataset.orderState。body>style .order[data-order-statenew] { color: green; } .order[data-order-statepending] { color: blue; } .order[data-order-statecanceled] { color: red; } /style div idorder classorder>!DOCTYPE html html body div>!DOCTYPE html html body div>// 找到所有带有>a namelistthe list/a ul lia hrefhttp://google.comhttp://google.com/a/li lia href/tutorial/tutorial.html/a/li lia hreflocal/pathlocal/path/a/li lia hrefftp://ftp.com/my.zipftp://ftp.com/my.zip/a/li lia hrefhttp://nodejs.orghttp://nodejs.org/a/li lia hrefhttp://internal.com/testhttp://internal.com/test/a/li /ul9.1 方案一遍历 getAttribute 过滤官方推荐let links document.querySelectorAll(a); for (let link of links) { let href link.getAttribute(href); // 注意必须用 getAttribute if (!href) continue; // 没有 href 特性跳过 if (!href.includes(://)) continue; // 没有协议跳过 if (href.startsWith(http://internal.com)) continue; // 内部链接跳过 link.style.color orange; }关键点这里用的是link.getAttribute(href)而不是link.href——因为link.href永远返回解析后的完整 URL如http://internal.com/test会保持完整但相对路径/tutorial会被拼成完整地址而我们恰恰需要 HTML 中原样书写的值才能用includes(://)和startsWith(...)做判定。这正是本章第六节结论的直接应用。9.2 方案二纯 CSS 选择器更简洁// 查找所有 href 中包含 :// 的链接但 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);完整可运行版本见 solution.view/index.html。两种方案对比方案一逻辑显式、便于逐步调试与增加复杂判断方案二一行选择器搞定利用 CSS 属性选择器*包含与^开头匹配代码量最少。十、总结何时用属性、何时用特性对比项属性property特性attribute类型任意值标准属性具有规范中描述的类型总是字符串名字大小写敏感大小写不敏感所在位置DOM 对象中HTML 文本中特性操作方法一览elem.hasAttribute(name)—— 检查特性是否存在elem.getAttribute(name)—— 获取特性值elem.setAttribute(name, value)—— 设置特性值elem.removeAttribute(name)—— 移除特性elem.attributes—— 所有特性的集合可迭代。日常开发以 DOM 属性为主仅在以下场景才使用特性需要非标准特性——若它以data-开头请改用dataset读写想读取 HTML 中原样书写的值——因为对应 DOM 属性可能已变形例如href属性永远返回完整 URL。本文的全部代码示例、任务与解答均可在仓库 2-ui/1-document/06-dom-attributes-and-properties/ 目录下找到章节正文见article.md两道练习的任务与官方解答分别位于1-get-user-attribute/task.mdsolution.md与2-yellow-links/task.md、solution.md含source.view/、solution.view/两个可直接运行的 HTML 页面。赞分享文档教程前端【免费下载链接】zh.javascript.info现代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 规范为基准通过简单但足够详细的内容为你讲解从基础到高阶的 JavaScript 相关知识。项目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info点击查看免费下载相关推荐使用>使用 data 属性与 dataset 读取元素自定义数据get user attribute 实战详解 本篇文章围绕 javascript.info 教程中文档/教程前端基于 DOM 特性与属性教程用 getAttribute 与 dataset 获取>基于 DOM 特性与属性教程用 getAttribute 与 dataset 获取 data 自定义特性 本文以《现代 JavaScript 教程中文版》中「文档教程前端从 DOM 读取>从 DOM 读取 data widget name 自定义属性getAttribute 与 dataset 完整指南 在现代 JavaScript 教程Mo文档/教程前端上一篇Obsidian Weread插件终极指南3步构建你的个人读书知识库下一篇xrdp终极指南免费实现Windows到Linux的完美远程桌面连接创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表