持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
当浏览器加载页面时,它会“读取”(或者称之为:“解析”)HTML 并从中生成 DOM 对象。对于元素节点,大多数标准的 HTML 特性(attributes)会自动变成 DOM 对象的属性(properties)。(译注:attribute 和 property 两词意思相近,为作区分,全文将 attribute 译为“特性”,property 译为“属性”,请读者注意区分。)
例如,如果标签是 <body id="page">,那么 DOM 对象就会有 body.id="page"。
但特性—属性映射并不是一一对应的!在本章,我们将带领你一起分清楚这两个概念,了解如何使用它们,了解它们何时相同何时不同。
DOM 属性
我们已经见过了内建 DOM 属性。它们数量庞大。但是从技术上讲,没有人会限制我们,如果我们觉得这些 DOM 还不够,我们可以添加我们自己的。
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 为所有元素添加一个新方法:
Element.prototype.sayHi = function() {
alert(`Hello, I'm ${this.tagName}`);
};
document.documentElement.sayHi(); // Hello, I'm HTML
document.body.sayHi(); // Hello, I'm BODY
所以,DOM 属性和方法的行为就像常规的 Javascript 对象一样:
- 它们可以有很多值。
- 它们是大小写敏感的(要写成
elem.nodeType,而不是elem.NoDeTyPe)。
HTML 特性
在 HTML 中,标签可能拥有特性(attributes)。当浏览器解析 HTML 文本,并根据标签创建 DOM 对象时,浏览器会辨别 标准的 特性并以此创建 DOM 属性。
所以,当一个元素有 id 或其他 标准的 特性,那么就会生成对应的 DOM 属性。但是非 标准的 特性则不会。
例如:
<body id="test" something="non-standard">
<script>
alert(document.body.id); // test
// 非标准的特性没有获得对应的属性
alert(document.body.something); // undefined
</script>
</body>
请注意,一个元素的标准的特性对于另一个元素可能是未知的。例如 "type" 是 <input> 的一个标准的特性(HTMLInputElement),但对于 <body>(HTMLBodyElement)来说则不是。规范中对相应元素类的标准的属性进行了详细的描述。
这里我们可以看到:
<body id="body" type="...">
<input id="input" type="text">
<script>
alert(input.type); // text
alert(body.type); // undefined:DOM 属性没有被创建,因为它不是一个标准的特性
</script>
</body>
所以,如果一个特性不是标准的,那么就没有相对应的 DOM 属性。那我们有什么方法来访问这些特性吗?
当然。所有特性都可以通过使用以下方法进行访问:
elem.hasAttribute(name)—— 检查特性是否存在。elem.getAttribute(name)—— 获取这个特性值。elem.setAttribute(name, value)—— 设置这个特性值。elem.removeAttribute(name)—— 移除这个特性。
这些方法操作的实际上是 HTML 中的内容。
我们也可以使用 elem.attributes 读取所有特性:属于内建 Attr 类的对象的集合,具有 name 和 value 属性。
下面是一个读取非标准的特性的示例:
<body something="non-standard">
<script>
alert(document.body.getAttribute('something')); // 非标准的
</script>
</body>
HTML 特性有以下几个特征:
- 它们的名字是大小写不敏感的(
id与ID相同)。 - 它们的值总是字符串类型的。
下面是一个使用特性的扩展示例:
<body>
<div id="elem" about="Elephant"></div>
<script>
alert( elem.getAttribute('About') ); // (1) 'Elephant',读取
elem.setAttribute('Test', 123); // (2) 写入
alert( elem.outerHTML ); // (3) 查看特性是否在 HTML 中(在)
for (let attr of elem.attributes) { // (4) 列出所有
alert( `${attr.name} = ${attr.value}` );
}
</script>
</body>
请注意:
getAttribute('About')—— 这里的第一个字母是大写的,但是在 HTML 中,它们都是小写的。但这没有影响:特性的名称是大小写不敏感的。- 我们可以将任何东西赋值给特性,但是这些东西会变成字符串类型的。所以这里我们的值为
"123"。 - 所有特性,包括我们设置的那个特性,在
outerHTML中都是可见的。 attributes集合是可迭代对象,该对象将所有元素的特性(标准和非标准的)作为name和value属性存储在对象中。