在 JavaScript 中,HTML DOM (Document Object Model) 是用于访问和操作 HTML 文档的标准编程接口。它将 HTML 文档结构化为树状形式,使得开发者可以轻松地通过 JavaScript 来改变文档的内容、结构和样式。
HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准。
DOM 节点
DOM 将 HTML 文档视为树结构,其中每个部分都是一个节点(node),节点类型包括:
- 文档节点:代表整个 HTML 文档(
document)。 - 元素节点:代表文档中的 HTML 元素(如
<p>、<div>)。 - 属性节点:代表元素的属性(如
class="myClass")。 - 文本节点:代表存放在元素和属性节点中的文本。
- 注释节点:代表 HTML 中的注释(
<!-- Comment -->)。
需要注意 Element Node 不含有 Text,具体参考:JS Element Node & Node Values。
节点属性
nodeName属性,只读,值为 tag name。nodeValue属性,element node = null,text node = text itself。nodeType属性,只读,节点类型,几种重要的 nodeType 数值如下:
| Node | Type | Example |
|---|---|---|
| ELEMENT_NODE | 1 | <h1 class="heading">W3Schools</h1> |
| ATTRIBUTE_NODE | 2 | class = “heading” (deprecated) |
| TEXT_NODE | 3 | W3Schools |
| COMMENT_NODE | 8 | <!-- This is a comment --> |
| DOCUMENT_NODE | 9 | The HTML document itself (the parent of <html>) |
| DOCUMENT_TYPE_NODE | 10 | <!Doctype html> |
<h1 id="id01">My First Page</h1>
<p id="id02">Hello</p>
<script>
<!-- H1 -->
var nodeName = document.getElementById("id01").nodeName;
<!-- null -->
var nodeValue = document.getElementById("id01").nodeValue;
<!-- Hello -->
var nodeValue = document.getElementById("id02").firstNode.nodeValue;
</script>访问元素
通过 DOM 提供的方法,可以访问 HTML 文档中的元素,常用方法包括:
getElementById(id): 通过元素 ID 获取单个元素。getElementsByTagName(name): 通过标签名称获取一组元素。getElementsByClassName(name): 通过类名获取一组元素。querySelector(selector): 返回文档中匹配指定 CSS 选择器的第一个元素。querySelectorAll(selector): 返回文档中匹配指定 CSS 选择器的所有元素的 NodeList。
// 通过元素ID获取元素
var elementById = document.getElementById("myElement");
// 通过标签名称获取元素集合
var elementsByTagName = document.getElementsByTagName("p");
// 通过类名获取元素集合
var elementsByClassName = document.getElementsByClassName("myClass");
// 使用CSS选择器获取第一个匹配元素
var firstElementBySelector = document.querySelector(".myClass");
// 使用CSS选择器获取所有匹配元素的NodeList
var allElementsBySelector = document.querySelectorAll("div.myClass");getElementsByTagName() 方法返回一个 HTMLCollection 对象。
HTMLCollection 对象是 HTML 元素的类似数组的集合。
但是 HTMLCollection 对象并不是数组,不能直接用数组的函数,如不能直接用 valueOf()、pop()、push() 或 join()。
NodeList 对象是从文档中提取的节点集合,与 HTMLCollection 对象几乎相同。
所有浏览器都会为属性 childNodes 返回一个 NodeList 对象。
大多数浏览器为 querySelectorAll() 方法返回 NodeList 对象。
操作元素属性
可以通过各种 DOM 属性和方法更改 HTML 元素:
innerHTML: 获取或设置元素的 HTML 内容。textContent: 设置或获取元素内的文本内容。setAttribute(name, value): 设置元素的属性值。removeAttribute(name): 删除元素的属性。.attribute: 直接修改元素属性getAttribute(): xxxremoveAttribute(): xxxhasAttribute(): xxx
// 获取元素
var element = document.getElementById("myElement");
// 设置属性
element.setAttribute("type", "button");
// 删除属性
element.removeAttribute("style");
// 获取属性
var elementClass = element.getAttribute("class");
// 更改HTML内容
element.innerHTML = '<a href="#">Click me!</a>';
// 更改文本内容
element.textContent = "Hello, World!";
// 也可以直接 .attribute 修改元素内容
document.getElementById("myImage").src = "landscape.jpg";操作 CSS 样式
JavaScript 也可以操作元素的 CSS 样式:
style: 通过该属性可以更改元素的样式(如元素的 style.color = ‘red’)。className: 获取或设置元素的 class。classList: 提供了对类名的各种操作,如添加、移除、切换类样式。getComputedStyle(ele).attr: 获取元素的 CSS 样式,带 attr 则获取更具体的样式
// 获取元素
var element = document.getElementById("myElement");
// 修改样式
element.style.color = "blue";
element.style.fontSize = "14px";
// 添加类
element.classList.add("new-class");
// 移除类
element.classList.remove("old-class");
// 切换类
element.classList.toggle("active-class");
// 检查类是否存在
var hasClass = element.classList.contains("another-class");
// 需要驼峰形式
getComputedStyle(oBox).backgroundColor;创建和删除元素
createElement(element): 创建一个 HTML 元素createTextNode(text): 创建一个 text nodeappendChild(child): 向元素添加新的子节点。removeChild(child): 移除元素的子节点。remove(): 删除当前节点。insertBefore(new, element): 将新元素插入到某元素之前replaceChild(new, old): 替换元素cloneNode(bool): 复制元素,1/true 还会复制子元素。write(text): 写入 HTML 输出流
// 创建一个新的 div 元素
var newDiv = document.createElement("div");
newDiv.id = "newDivId";
newDiv.className = "new-div-class";
newDiv.innerHTML = "This is a new div element";
// 创建一个包含 "This is a new paragraph." 文本的 p 节点
const para = document.createElement("p");
const node = document.createTextNode("This is a new paragraph.");
para.appendChild(node);
// 将新元素添加到文档
element.appendChild(newDiv);
// 移除子元素
element.removeChild(newDiv);
// 删除当前节点
element.remove();
// 插入元素
document.body.insertBefore(newP, firstDiv);Events 事件处理
DOM 允许你给元素分配事件处理程序,响应用户操作:
addEventListener(type, listener, useCapture=False): 添加事件监听器。removeEventListener(type, listener): 移除事件监听器。onclick,onmouseover,onmouseout,onkeydown,onload等: 分配或处理事件。
常见的 Event 事件有 JS Events 常见事件。
添加事件监听器的时候,还可以配置事件传播机制,详见 JS Events 事件传播。
function handleClick() {
alert("Element was clicked!");
}
// 获取元素
var button = document.getElementById("myButton");
// 添加事件监听器
button.addEventListener("click", handleClick);
// 移除事件监听器
button.removeEventListener("click", handleClick);
// 添加事件监听器
document.getElementById(id).onclick = handleClick;
// 不止 document 中的元素可以添加 EventListener
window.addEventListener("resize", function () {
document.getElementById("demo").innerHTML = _sometext_;
});遍历 DOM 节点
parentNode: 访问元素的父节点。childNodes[index]: 获取元素的子节点列表。firstChild和lastChild: 分别访问元素的第一个和最后一个子节点。nextSibling和previousSibling: 分别访问元素的下一个和上一个兄弟节点。
// 获取元素
var list = document.getElementById("myList");
// 获取父元素
var parentOfList = list.parentNode;
// 遍历子节点
for (var i = 0; i < list.childNodes.length; i++) {
console.log(list.childNodes[i]);
}
// 获取并遍历兄弟元素
var sibling = list.nextSibling;
while (sibling) {
if (sibling.nodeType === 1) {
// Element node
console.log(sibling);
}
sibling = sibling.nextSibling;
}HTML Objects
The first HTML DOM Level 1 (1998), defined 11 HTML objects, object collections, and properties. These are still valid in HTML5.
Later, in HTML DOM Level 3, more objects, collections, and properties were added.
| Property | Description | DOM |
|---|---|---|
| document.anchors | Returns all <a> elements that have a name attribute | 1 |
| document.applets | Deprecated | 1 |
| document.baseURI | Returns the absolute base URI of the document | 3 |
| document.body | Returns the <body> element | 1 |
| document.cookie | Returns the document’s cookie | 1 |
| document.doctype | Returns the document’s doctype | 3 |
| document.documentElement | Returns the <html> element | 3 |
| document.documentMode | Returns the mode used by the browser | 3 |
| document.documentURI | Returns the URI of the document | 3 |
| document.domain | Returns the domain name of the document server | 1 |
| document.domConfig | Obsolete. | 3 |
| document.embeds | Returns all <embed> elements | 3 |
| document.forms | Returns all <form> elements | 1 |
| document.head | Returns the <head> element | 3 |
| document.images | Returns all <img> elements | 1 |
| document.implementation | Returns the DOM implementation | 3 |
| document.inputEncoding | Returns the document’s encoding (character set) | 3 |
| document.lastModified | Returns the date and time the document was updated | 3 |
| document.links | Returns all <area> and <a> elements that have a href attribute | 1 |
| document.readyState | Returns the (loading) status of the document | 3 |
| document.referrer | Returns the URI of the referrer (the linking document) | 1 |
| document.scripts | Returns all <script> elements | 3 |
| document.strictErrorChecking | Returns if error checking is enforced | 3 |
| document.title | Returns the <title> element | 1 |
| document.URL | Returns the complete URL of the document | 1 |
HTML Form Validation
JS 动画小示例
点击按钮后,会有一个小红色矩形从左上角运动到右下角。W3Schools Tryit Editor
<!DOCTYPE html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
</style>
<body>
<p><button onclick="myMove()">Click Me</button></p>
<div id="container">
<div id="animate"></div>
</div>
<script>
function myMove() {
let id = null;
const elem = document.getElementById("animate");
let pos = 0;
clearInterval(id);
id = setInterval(frame, 5);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + "px";
elem.style.left = pos + "px";
}
}
}
</script>
</body>
</html>