
2025-02-19 日报 Day102

今日的鸡汤
往后岁月,愿你摆正自己,见天地之大、众生之广,行稳致远,活出精彩人生。
今日学习内容
1、JS 红皮书 P414-422 第十四章:DOM
今日笔记
1、Element类型: 除了Document 类型,Element 类型就是Web开发中最常用的类型了。Element 表示XML或HTML元素,对外暴露出访问元素标签名、子节点和属性的能力。Element 类型的节点具有以下特征:
nodeType: 1
nodeName: 元素的标签名
nodeValue: null
parentNode: 指向父元素
HTML元素: 所有 HTML 元素都通过 HTMLElement 类型表示,包括其直接实例和间接实例。另外,HTMLElement直接继承 Element 并增加了一些属性。每个属性都对应下列属性之一,它们是所有 HTML 元素上都有的标准属性:
id,元素在文档中的唯一标识符;
title,包含元素的额外信息,通常以提示条形式展示;
lang,元素内容的语言代码(很少用);
dir,语言的书写方向(”ltr”表示从左到右,”rtl”表示从右到左,同样很少用);
className,元素的类名(class 属性);
这个元素中的所有属性都可以使用下列 JavaScript 代码读取:
所有这些都可以用来获取对应的属性值,也可以用来修改相应的值。比如有下面的 HTML 元素:
1 | let div = document.getElementById("myDiv"); |
- 取得属性: 每个元素都有零个或多个属性,通常用于为元素或其内容附加更多信息。与属性相关的 DOM 方法主要有 3 个:getAttribute()、setAttribute()和 removeAttribute()。这些方法主要用于操纵属性,包括在 HTMLElement 类型上定义的属性。下面看一个例子:
1
2
3
4
5
6let div = document.getElementById("myDiv");
alert(div.getAttribute("id")); // "myDiv"
alert(div.getAttribute("class")); // "bd"
alert(div.getAttribute("title")); // "Body text"
alert(div.getAttribute("lang")); // "en"
alert(div.getAttribute("dir")); // "ltr" - 设置属性: 通过 setAttribute() 方法可以设置元素的属性值。这个方法接受两个参数:要设置的属性名和要设置的值。比如:注意,在 DOM 对象上添加自定义属性,如下面的例子所示,不会自动让它变成元素的属性:
1
2
3
4
5div.setAttribute("id", "someOtherId");
div.setAttribute("class", "ft");
div.setAttribute("title", "Some other text");
div.setAttribute("lang","fr");
div.setAttribute("dir", "rtl");这个例子添加了一个自定义属性 mycolor 并将其值设置为”red”。在多数浏览器中,这个属性不会自动变成元素属性。因此调用 getAttribute()取得 mycolor 的值会返回 null。1
2div.mycolor = "red";
alert(div.getAttribute("mycolor")); // null(IE 除外)
最后一个方法 removeAttribute()用于从元素中删除属性。这样不单单是清除属性的值,而是会把整个属性完全从元素中去掉,如下所示:
div.removeAttribute(“class”);
这个方法用得并不多,但在序列化 DOM 元素时可以通过它控制要包含的属性。 - attributes属性: Element 类型是唯一使用 attributes 属性的 DOM 节点类型。attributes 属性包含一个NamedNodeMap 实例,是一个类似 NodeList 的“实时”集合。元素的每个属性都表示为一个 Attr 节点,并保存在这个 NamedNodeMap 对象中。NamedNodeMap 对象包含下列方法:
getNamedItem(name),返回 nodeName 属性等于 name 的节点;
removeNamedItem(name),删除 nodeName 属性等于 name 的节点;
setNamedItem(node),向列表中添加 node 节点,以其 nodeName 为索引;
item(pos),返回索引位置 pos 处的节点。
attributes 属性中的每个节点的 nodeName 是对应属性的名字,nodeValue 是属性的值。比如,要取得元素 id 属性的值,可以使用以下代码:
let id = element.attributes.getNamedItem(“id”).nodeValue;
下面是使用中括号访问属性的简写形式:
let id = element.attributes[“id”].nodeValue;
同样,也可以用这种语法设置属性的值,即先取得属性节点,再将其 nodeValue 设置为新值,如下所示:
element.attributes[“id”].nodeValue = “someOtherId”;
removeNamedItem()方法与元素上的 removeAttribute()方法类似,也是删除指定名字的属性。
下面的例子展示了这两个方法唯一的不同之处,就是removeNamedItem()返回表示被删除属性的Attr节点:
let oldAttr = element.attributes.removeNamedItem(“id”);
setNamedItem()方法很少使用,它接收一个属性节点,然后给元素添加一个新属性,如下所示:
element.attributes.setNamedItem(newAttr);
一般来说,因为使用起来更简便,通常开发者更喜欢使用 getAttribute()、removeAttribute() 和 setAttribute()方法,而不是刚刚介绍的 NamedNodeMap 对象的方法。 - 创建元素: 可以使用 document.createElement()方法创建新元素。这个方法接收一个参数,即要创建元素的标签名。在 HTML 文档中,标签名是不区分大小写的,而 XML 文档(包括 XHTML)是区分大小写的。要创建元素,可以使用下面的代码:元素被添加到文档树之后,浏览器会立即将其渲染出来。之后再对这个元素所做的任何修改,都会立即在浏览器中反映出来。
1
2
3
4
5
6let div = document.createElement("div");
div.id = "myNewDiv";
div.className = "box";
document.body.appendChild(div);- 元素后代: 元素可以拥有任意多个子元素和后代元素,因为元素本身也可以是其他元素的子元素。childNodes属性包含元素所有的子节点,这些子节点可能是其他元素、文本节点、注释或处理指令。不同浏览器在识别这些节点时的表现有明显不同。比如下面的代码:
在解析以上代码时,1
2
3
4
5<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>- 元素会包含 7 个子元素,其中 3 个是
- 元素,还有 4 个 Text 节点(表示
- 元素周围的空格)。如果把元素之间的空格删掉,变成下面这样,则所有浏览器都会返回同样数量的子节点:
- Item 1
- Item 2
- Item 3
- nodeType: 3
- nodeName: “#text”
- nodeValue: 文本内容
- parentNode: 指向父节点
- 不支持子节点
Text 节点中包含的文本可以通过 nodeValue 属性访问,也可以通过 data 属性访问,这两个属性包含相同的值。修改 nodeValue 或 data 的值,也会在另一个属性反映出来。文本节点暴露了以下操作文本的方法:
appendData(text),向节点末尾添加文本 text;
deleteData(offset, count),从位置 offset 开始删除 count 个字符;
insertData(offset, text),在位置 offset 插入 text;
replaceData(offset, count, text),用 text 替换从位置 offset 到 offset + count 的文本;
splitText(offset),在位置 offset 将当前文本节点拆分为两个文本节点;
substringData(offset, count),提取从位置 offset 到 offset + count 的文本。
除了这些方法,还可以通过 length 属性获取文本节点中包含的字符数量。这个值等于 nodeValue.length 和 data.length。 - 创建文本节点: document.createTextNode()可以用来创建新文本节点,它接收一个参数,即要插入节点的文本。跟设置已有文本节点的值一样,这些要插入的文本也会应用 HTML 或 XML 编码,如下面的例子所示:
1
2
3
4
5
6let textNode = document.createTextNode("<strong>Hello</strong> world!");
let element = document.createElement("div");
element.className = "message";
let textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);- 规范化文本节点: DOM 文档中的同胞文本节点可能导致困惑,因为一个文本节点足以表示一个文本字符串。同样,DOM 文档中也经常会出现两个相邻文本节点。为此,有一个方法可以合并相邻的文本节点。这个方法叫 normalize(),是在 Node 类型中定义的(因此所有类型的节点上都有这个方法)。在包含两个或多个相邻文本节点的父节点上调用 normalize()时,所有同胞文本节点会被合并为一个文本节点,这个文本节点的 nodeValue 就等于之前所有同胞节点 nodeValue 拼接在一起得到的字符串。来看下面的例子:
1
2
3
4
5
6
7
8
9
10
11let element = document.createElement("div");
element.className = "message";
let textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
let anotherTextNode = document.createTextNode("Yippee!");
element.appendChild(anotherTextNode);
document.body.appendChild(element);
alert(element.childNodes.length); // 2
element.normalize();
alert(element.childNodes.length); // 1
alert(element.firstChild.nodeValue); // "Hello world!Yippee!" - 拆分文本节点: splitText()方法可以将一个文本节点拆分为两个文本节点。这个方法接收一个参数,表示要拆分的位置。比如:
1
2
3
4
5
6
7
8
9let element = document.createElement("div");
element.className = "message";
let textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
let newNode = element.firstChild.splitText(5);
alert(element.firstChild.nodeValue); // "Hello"
alert(newNode.nodeValue); // " world!"
alert(element.childNodes.length); // 2
- 元素后代: 元素可以拥有任意多个子元素和后代元素,因为元素本身也可以是其他元素的子元素。childNodes属性包含元素所有的子节点,这些子节点可能是其他元素、文本节点、注释或处理指令。不同浏览器在识别这些节点时的表现有明显不同。比如下面的代码:
此页目录
2025-02-19 日报 Day102