DOM与BOM
DOM概述
文档对象模型(DOM)是针对HTML和XML文档的一个应用程序编程接口(API),它可以将任何HTML或XML文档描绘成一个由多层节点和对象构成的结构集合。DOM1级定义了一个Node接口,该接口由DOM中所有的节点类型实现,如图中Document类型、Element类型等。所有节点使用nodeType来标识它所属类型,其具体信息则由nodeName和nodeValue属性描述。以下面HTML为例:
<!DOCTYPE html> <!-- 我是注释--> <html lang="en"> <head> <meta charset="UTF-8"> <title>Sample Page</title> </head> <body> <p id="one">Hello World!</p> </body> </html>
常见的DOM操作
访问子节点
每个节点都有一个childNodes属性来访问该节点的子节点,返回的是一个NodeList对象(它是一个类数组对象,并不是Array实例)。NodeList对象是基于DOM结构动态执行查询的结果,每一次访问NodeList都会运行一次基于文档的查询,来获取最新的HTML页面节点树,因此应该尽量减少访问NodeList,可以考虑使用变量将NodeList对象缓存起来。也即它会随着HTML页面的节点层次改变而改变。要注意的是,childNodes属性返回的NodeList会将HTML页面中节点之间的换行符和空白符作为一个文档节点也添加进子节点列表里,看下面示例:
let child = document.body.childNodes;//获取body节点的子节点 alert(child.length); //上面HTML页面中body只有一个p子节点,但子节点列表长度显示为3 let pairs = []; for(let i=0;i<child.length;i++){ let nodeType = child[i].nodeType; let nodeName = child[i].nodeName; let nodeValue = child[i].nodeValue; pairs.push("("+nodeType+")"+nodeName+" = "+nodeValue); } alert(pairs.join(","));//输出为 (3)#text=[换行符],(1)P=null,(3)#text=[换行符]
因此引入了children属性,它返回的HTMLCollection对象(也是类数组的 HTML 元素列表(集合))只包含Element类型的子节点。
let child = document.body.children;
let pairs=[];
alert(child.length); //长度显示为1
for(let i=0;i<child.length;i++){
let nodeType = child[i].nodeType;
let nodeName = child[i].nodeName;
let nodeValue = child[i].nodeValue;
pairs.push("("+nodeType+")"+nodeName+" = "+nodeValue);
}
alert(pairs.join(",")); //输出 (1)P=null
查找元素
- getElementById()
该方法根据元素的ID来查找相应元素,若不存在则返回null
- getElementsByTagName()
该方法根据元素的标签名查找所有符合的元素,返回的是一个NodeList(在HTML文档中返回的是HTMLCollection对象)。另外,可以传入"*"作为参数,表示查找整个页面的全部元素
- getElementsByName()
该方法是HTMLDocument类型特有的方法,返回带有给定name特性的所有元素的一个NodeList对象。通常,使用该方法来获取具有相同name特性的单选按钮。如下面示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Sample Page</title> <script src="test.js"></script> </head> <body> <ul id="unordered"> <li><input type="radio" value="red" name="color" id="colorRed"> <label for="colorRed">Red</label></li> <li><input type="radio" value="green" name="color" id="colorGreen"> <label for="colorGreen">Green</label></li> <li><input type="radio" value="blue" name="color" id="colorBlue"> <label for="colorBlue">Blue</label></li> </ul> </body> </html>
let e = document.getElementsByName("color"); alert(e); //类型为NodeList let pairs=[]; for(let i=0;i<e.length;i++){ let nodeId = e[i].getAttribute("id"); //获取节点的id,getAttribute()方法用于查找给定属性名的属性,并返回该属性的值 let nodeValue = e[i].getAttribute("value"); //获取节点的value pairs.push(nodeId +" = "+nodeValue); } alert(pairs.join(" "));//输出为 colorRed=red colorGreen=green colorBlue=blue
attributes属性
Element类型是使用attributes属性的唯一一个DOM节点类型,该属性包含一个NamedNodeMap集合,以键值对形式(nodeName:nodeValue)存储着节点特性。实际上节点特性也可以看做一个个节点,用Attr类型表示,nodeType=11,它的nodeName就是该特性的标签名,nodeValue是该特性的值。attributes属性在遍历元素特性上很方便,选取上面一个input元素作为示例:
let e = document.getElementById("colorRed"); let pairs=[]; for(let i=0;i<e.attributes.length;i++){ let attrName = e.attributes[i].nodeName;//这里的nodeName就是某特性的标签名 let attrValue = e.attributes[i].nodeValue;//nodeValue表示某特性的值 pairs.push(attrName +" = "+attrValue); } alert(pairs.join(", "));//输出 type=radio, value=red, name=color, id=colorRed
创建节点
- createElement()
- createTextNode()
let parentNode = document.getElementById("unordered");//首先获取父节点,便于将新创建节点作为其子节点 let newNode = document.createElement("li");//创建元素节点 let textNode = document.createTextNode("Hello World");//创建文本节点 newNode.appendChild(textNode);//将文本节点作为新元素节点的子节点 parentNode.appendChild(newNode);
innerText属性和innerHTML属性的区别
innerText属性处理的是普通文本内容,innerHTML属性处理的是HTML字符串。我们仍以上面单选框的HTML页面为例:
let e = document.getElementById("unordered"); //获取<ul>节点 alert(e.innerText); //仅输出Text内容 alert(e.innerHTML); //输出<ul>下的所有HTML代码 e.innerHTML = "<li><input type=\"radio\" value=\"yellow\" name=\"color\" id=\"colorYellow\">\n" + "<label for=\"colorYellow\">Yellow</label></li>"; //重写<ul>节点的子树,也即此时只剩下一个单选框Yellow,移除了原来三个input
值得注意的是,使用 innerText 和 innerHTML 属性替换子节点可能会导致浏览器的内存问题。假设某个元素节点有一个事件处理程序或一个作为属性的JavaScript对象,当使用上述属性将该元素移除后,元素节点与事件处理程序之间的绑定依旧存在于内存中,当频繁出现这种情况时会造成内存占用增加。
另外,使用 innerHTML 属性要比通过多次DOM操作先创建节点再指定它们之间的关系(像4.中编写的代码)要有效率得多,因为在设置innerHTML属性时会创建一个HTML解析器,它是在浏览器级别代码基础上运行的。
BOM概述
浏览器对象模型(BOM),提供了与浏览器交互的一些对象。
- Window:作为BOM的顶级对象,可以说window既是浏览器窗口的一个接口,也是浏览器环境的全局对象;
- Location:操作URL的接口,可以通过document.location或window.location属性访问;
- Navigator:表示用户代理的状态和标识的接口,由window.navigator属性获取;
- Screen:表示一个屏幕窗口,由window.screen属性获取;
- History:提供浏览器会话历史记录操作的一个接口;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)