在大多数的文章中,attribute 一般被翻译为“特性”,property 被译为“属性”。
把结论写在最前面,如果你全都懂,后面就不用看了。
html attribute | dom property |
---|---|
值永远是字符串或 null | 值可以是任意合法 js 类型 |
大小写不敏感 | 大小写敏感 |
不存在时返回 null | 不存在时返回 undefined |
对于 href, 返回 html 设置的值 | 对于 href 返回解析后的完整 url |
更新 value, 属性也更新 | 更新 value, 特性不更新 |
当我们书写 HTML 代码的时候,我们为 HTML <abbr title="Element">元素</abbr>设置<abbr title="attribute">特性</abbr> ,例如:
<input id="name" value="justjavac" />
我们写了一个 input 标签,并给他定义了 2 个<abbr title="attribute">特性</abbr> (id 和 value)。当浏览器解析这段代码的时候,会把 html 源码解析为 DOM 对象,确切的说是解析为 HTMLInputElement 对象。HTMLInputElement 的继承关系是:
HTMLInputElement
↓
HTMLElement
↓
Element
↓
Node
↓
EventTarget
↓
Object
通过查看文档会发现,HTMLInputElement 的原型上定义了很多<abbr title="property">属性</abbr>和方法,例如 form, name, type, alt, checked, src, value 等等,还有从 HTMLElement 继承来的 id, title, clientTop 等等。
如果仔细找找,就不难发现其中就有我们为 input 标签定义的<abbr title="attribute">特性</abbr>:id 和 value。当浏览器解析网页时,将 HTML <abbr title="attribute">特性</abbr>映射为了 DOM <abbr title="property">属性</abbr>。
而 Element 类还有一个 attributes 属性,里面包含了所有的特性。
但是,HTML attribute 和 DOM property 并不总是一对一的关系。
当浏览器解析完 HTML 后,生成的 DOM 是一个继承自 Object 的常规 JavaScript 对象,因此我们可以像操作任何 JS 对象那样来操作 DOM 对象。
const el = document.getElementById('name')
el.foo = 'bar'
el.user = { name: 'jjc', age: '18'}
也可以为其添加方法。如果你想给每个 html 元素都添加属性或方法,甚至可以直接修改 Element.prototype,不过我们不推荐这么做。
和 DOM 属性类似,除了那些规范里定义的标准特性外,HTML 也可以添加非标准的属性,例如:
<input id="name" value="justjavac" foo="bar" />
当 HTML 特性映射为 DOM 属性时,只映射标准属性,访问非标准属性将得到 undefined。
const el = document.getElementById('name')
el.foo === undefined
好在 DOM 对象也提供了操作特性的 api:
以上 API 定义在 Element 上。
根据 HTML 规范,标签以及特性名是不区分大小写的,因此以下代码是一样的:
el.getAttribute('id')
el.getAttribute('ID')
el.getAttribute('iD')
并且,特性永远都是字符串或 null。如果我们为特性设置非字符串的值,则引擎会将此值转换为字符串。属性是具有类型的:
el.getAttribute('checked') === '' // 特性是字符串
el.checked === false // 属性是 boolean 类型的值
el.getAttribute('style') === 'color:blue' // 特性是字符串
typeof el.style === 'object' // 属性是 cssStyleDeclaration 对象
即使都是字符串,属性和特性也可能不同,有一个例外就是 href:
el.getAttribute('href') === '#tag' // 特性原样返回 html 设置的值
el.href === 'http://jjc.fun#tag' // 属性返回解析后的完整 uri
当标准的特性更新时,对应的属性也会更新;反之亦然。
但是 input.value 的同步是单向的,只是 attribute --> property。当修改特性时,属性也会更新;但是修改属性后,特性却还是原值。
el.setAttribute('value', 'jjc'); // 修改特性
el.value === 'jjc' // 属性也更新了
el.value = 'newValue'; // 修改属性
el.getAttribute('value')) === 'jjc' // 特性没有更新
非标准 HTML 特性并不会自动映射为 DOM 属性。当我们使用 data- 开头的特性时,会映射到 DOM 的 dataset 属性。中划线格式会变成驼峰格式:
el.setAttribute('data-my-name', 'jjc');
el.dataset.myName === 'jjc'
el.setAttribute('data-my-AGE', 18);
el.dataset.myAge === '18'
HTML 允许我们自定义标签,也可以扩展标签的特性,但是我们推荐使用已经进入 HTML5 规范的自定义特性 data-*。比如我们想为 div 标签增加一个 age 特性,我们可以有 2 种选择:
<div age="18">justjavac</div>
<div data-age="18">justjavac</div>
虽然第一种代码更短,但是却有一个潜在的风险。因为 HTML 规范是一直发展变化的,也许在未来的某个版本中,age 被添加进了标准特性里面,这将会引起潜在的 bug。
阅读原文:HTML attribute 和 DOM property
讨论地址:#15
DOM是很慢的,其元素非常庞大,页面的性能问题鲜有由JS引起的,大部分都是由DOM操作引起的。虚拟的DOM的核心思想是:对复杂的文档DOM结构,提供一种方便的工具,进行最小化地DOM操作。
浏览器解析HTML文档生成DOM树的过程,以下是一段HTML代码,以此为例来分析解析HTML文档的原理.解析HTML文档构建DOM树的理解过程可分为两个主要模块构成,即标签解析、DOM树构建
javascript获取DOM对象的多种方法:通过id获取 、通过class获取、通过标签名获取、通过name属性获取、通过querySelector获取、通过querySelectorAll获取等
遍历DOM节点常用一般用节点的 childNodes, firstChild, lastChild, nodeType, nodeName, nodeValue属性。在获取节点nodeValue时要注意,元素节点的子文本节点的nodeValue才是元素节点中文本的内容。
要构建自己的虚拟DOM,需要知道两件事。你甚至不需要深入 React 的源代码或者深入任何其他虚拟DOM实现的源代码,因为它们是如此庞大和复杂——但实际上,虚拟DOM的主要部分只需不到50行代码。
事件冒泡: 即事件开始时由最具体的元素(文档中嵌套层数最深的那个点)接收,事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件.与此同时,我们还需要了解dom事件绑定处理的几种方式:
先列出我的理解,然后再从具体的例子中说明:DOM操作本身应该是同步的(当然,我说的是单纯的DOM操作,不考虑ajax请求后渲染等);DOM操作之后导致的渲染等是异步的(在DOM操作简单的情况下,是难以察觉的)
早期由于浏览器厂商对于浏览器市场的争夺,各家浏览器厂商对同一功能的JavaScript的实现都不进相同,本节内容介绍JavaScript的DOM事件模型及事件处理程序的分类。
设置定义属性值 :data-value=.., 2.直接获取 3.通过this.$refs.***获取 1.目标DOM定义ref值: 2.通过 【this.$refs.***.属性名】 获取相关属性的值: this.$refs.*** 获取到对应的元素 ...
框架用多了,你还记得那些操作 DOM 的纯 JS 语法吗?看看这篇文章,来回顾一下~ 操作 className,addClass给元素增加 class,使用 classList 属性
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!