DOM基础

DOM概述

DOM(Document Object Model)是HTML和XML文档的编程接口。

什么是DOM

// DOM将文档表示为节点树
// JavaScript可以通过DOM API操作页面内容

// DOM不是JavaScript的一部分
// 它是浏览器提供的Web API

DOM的作用

// 1. 获取页面元素
const title = document.querySelector("h1");

// 2. 修改页面内容
title.textContent = "东巴文";

// 3. 修改样式
title.style.color = "red";

// 4. 响应用户操作
title.addEventListener("click", () => {
    console.log("点击了标题");
});

// 5. 创建和删除元素
const div = document.createElement("div");
document.body.appendChild(div);

DOM树结构

DOM将HTML文档表示为树形结构。

基本结构

<!DOCTYPE html>
<html>
<head>
    <title>东巴文</title>
</head>
<body>
    <h1>标题</h1>
    <p>段落</p>
    <ul>
        <li>项目1</li>
        <li>项目2</li>
    </ul>
</body>
</html>

树形图示

Document
└── html (Element)
    ├── head (Element)
    │   └── title (Element)
    │       └── "东巴文" (Text)
    └── body (Element)
        ├── h1 (Element)
        │   └── "标题" (Text)
        ├── p (Element)
        │   └── "段落" (Text)
        └── ul (Element)
            ├── li (Element)
            │   └── "项目1" (Text)
            └── li (Element)
                └── "项目2" (Text)

节点层级

const html = document.documentElement;
const head = document.head;
const body = document.body;

console.log(html.parentNode);      // Document
console.log(body.parentNode);      // html
console.log(body.childNodes);      // NodeList
console.log(body.children);        // HTMLCollection

节点类型

DOM中有多种节点类型。

节点类型常量

类型 常量 nodeType 说明
元素节点 Node.ELEMENT_NODE 1 HTML元素
属性节点 Node.ATTRIBUTE_NODE 2 元素属性
文本节点 Node.TEXT_NODE 3 文本内容
注释节点 Node.COMMENT_NODE 8 注释
文档节点 Node.DOCUMENT_NODE 9 document
文档类型 Node.DOCUMENT_TYPE_NODE 10 DOCTYPE

检查节点类型

const element = document.querySelector("div");
const text = element.firstChild;

console.log(element.nodeType);  // 1
console.log(element.nodeName);  // "DIV"

console.log(text.nodeType);     // 3
console.log(text.nodeName);     // "#text"

// 检查是否为元素节点
console.log(element.nodeType === Node.ELEMENT_NODE);  // true
console.log(element.nodeType === 1);  // true

不同类型的节点

// 元素节点
const div = document.createElement("div");
console.log(div.nodeType);  // 1

// 文本节点
const text = document.createTextNode("东巴文");
console.log(text.nodeType);  // 3

// 注释节点
const comment = document.createComment("注释");
console.log(comment.nodeType);  // 8

// 文档节点
console.log(document.nodeType);  // 9

节点关系

节点之间存在父子、兄弟关系。

父子关系

const parent = document.querySelector("ul");
const child = parent.querySelector("li");

// 父节点
console.log(child.parentNode);      // ul元素
console.log(child.parentElement);   // ul元素

// 子节点(包含所有类型)
console.log(parent.childNodes);     // NodeList(包含文本节点)

// 子元素(只有元素节点)
console.log(parent.children);       // HTMLCollection

// 第一个/最后一个子节点
console.log(parent.firstChild);     // 可能是文本节点
console.log(parent.lastChild);

// 第一个/最后一个子元素
console.log(parent.firstElementChild);  // 第一个li
console.log(parent.lastElementChild);   // 最后一个li

兄弟关系

const li = document.querySelector("li");

// 前一个/后一个节点
console.log(li.previousSibling);    // 可能是文本节点
console.log(li.nextSibling);

// 前一个/后一个元素
console.log(li.previousElementSibling);
console.log(li.nextElementSibling);

遍历节点

// 遍历所有子节点
function traverseChildren(parent) {
    const children = parent.childNodes;
    for (let i = 0; i < children.length; i++) {
        console.log(children[i]);
    }
}

// 遍历所有子元素
function traverseElements(parent) {
    for (const child of parent.children) {
        console.log(child);
    }
}

// 递归遍历所有后代
function traverseAll(element, callback) {
    callback(element);
    for (const child of element.children) {
        traverseAll(child, callback);
    }
}

document对象

document对象代表整个HTML文档。

文档属性

// 文档信息
console.log(document.title);        // 页面标题
console.log(document.URL);          // 完整URL
console.log(document.domain);       // 域名
console.log(document.referrer);     // 来源URL
console.log(document.characterSet); // 字符编码

// 修改标题
document.title = "新标题";

文档方法

// 获取元素
document.getElementById("id");
document.getElementsByTagName("div");
document.getElementsByClassName("class");
document.querySelector(".class");
document.querySelectorAll("div");

// 创建元素
document.createElement("div");
document.createTextNode("文本");
document.createComment("注释");
document.createDocumentFragment();

// 写入内容
document.write("<h1>标题</h1>");
document.writeln("内容");
// 注意:document.write会覆盖整个文档

特殊集合

// 文档中的特殊集合
console.log(document.forms);      // 所有form元素
console.log(document.images);     // 所有img元素
console.log(document.links);      // 所有a元素(有href)
console.log(document.anchors);    // 所有a元素(有name)
console.log(document.scripts);    // 所有script元素

// 访问表单
const form = document.forms[0];
const formById = document.forms["formId"];

// 访问图片
const img = document.images[0];

文档状态

// 文档加载状态
console.log(document.readyState);
// "loading" - 正在加载
// "interactive" - 可交互
// "complete" - 完成

// DOMContentLoaded事件
document.addEventListener("DOMContentLoaded", () => {
    console.log("DOM已加载");
});

// load事件
window.addEventListener("load", () => {
    console.log("页面完全加载");
});

获取元素方法对比

方法 返回值 实时 东巴文建议
getElementById 单个元素 - 按ID获取
getElementsByTagName HTMLCollection 按标签名
getElementsByClassName HTMLCollection 按类名
querySelector 单个元素 CSS选择器
querySelectorAll NodeList CSS选择器

下一步

掌握了DOM基础后,让我们继续学习:

  1. DOM选择器 - 学习DOM选择器
  2. DOM操作 - 学习DOM操作
  3. DOM属性与样式 - 学习属性与样式

东巴文(db-w.cn) - 让编程学习更简单

🌳 东巴文寄语:DOM是JavaScript操作网页的桥梁,理解DOM树结构和节点关系是前端开发的基础。掌握document对象和各种节点操作方法,能让你自由地操控页面。在 db-w.cn,我们帮你打好DOM基础!