视频加载失败

JavaScript的DOM之节点

2387 字
12 分钟
JavaScript的DOM之节点

关于JavaScript的DOM,其实vue和react这类框架已经帮我们解决了,学习本章的意义也是了解其原理,在一般开发中,很少直接操作dom,也不建议直接操作dmo

DOM基本概念#

  • DOM是JS操控HTML和CSS的桥梁
  • DOM使JS操作HTML变得优雅

DOM简介

  • DOM(Document Object Model,文档对象模型)是 JavaScript操作HTML文档的接口,使文档操作变得非常优 雅、简便
  • DOM最大的特点就是将文档表示为节点树

DOM节点树

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>慕课网</h1>
<div>
<h2>程序员的梦工厂</h2>
<img src="logo.png">
<div class="box">
慕课专栏
</div>
</div>
</body>
</html>

NodeType#

节点的nodeType属性可以显示这个节点具体的类型

nodeType 值节点类型
1元素节点,例如 p 和 div
3文本节点
8注释节点
9Document 文档节点
10DocumentType 文档类型节点(DTD)

访问元素节点

  • 所谓“访问”元素节点,就是指“得到”、“获取”页面上 的元素节点
  • 对节点进行操作,第一步就是要得到它
  • 访问元素节点主要依靠document对象

Document#

  • document对象是DOM中最重要的东西,几乎所有DOM的 功能都封装在了document对象中

  • document对象也表示整个HTML文档,它是DOM节点树 的根

  • document对象的nodeType属性值是9

  • 访问元素节点的常用方法

    方法功能兼容性
    document.getElementById()通过 ID 获取元素IE6+
    document.getElementsByTagName()通过标签名获取元素集合IE6+
    document.getElementsByClassName()通过类名获取元素集合IE9+
    document.querySelector()通过 CSS 选择器获取第一个匹配的元素IE8 部分兼容,IE9+ 完全兼容
    document.querySelectorAll()通过 CSS 选择器获取所有匹配的元素集合IE8 部分兼容,IE9+ 完全兼容

获取节点#

getElementById()#

document.getElementById()功能是通过id得到元素节点

<div id="box">我是一个盒子</div>
<p id="para">我是一个段落</p>
<script>
var box = document.getElementById('box');
var para = document.getElementById('para');
</script>

注意事项

  • 如果页面上有相同id的元素,则只能得到第一个
  • 不管元素藏的位置有多深,都能通过id把它找到

getElementsByTagName()#

getElementsByTagName()方法的功能是通过标签名得到 节点数组

<p>我是段落</p>
<p>我是段落</p>
<p>我是段落</p>
<p>我是段落</p>
<script>
var ps = document.getElementsByTagName('p');//数组
</script>

注意事项

  • 数组方便遍历,从而可以批量操控元素节点
  • 即使页面上只有一个指定标签名的节点,也将得到长度为1 的数组
  • 任何一个节点元素也可以调用getElementsByTagName() 方法,从而得到其内部的某种类的元素节点

getElementsByClassName()#

getElementsByClassName()方法的功能是通过类名得到节点数组

<div class="spec">我是盒子</div>
<div>我是盒子</div>
<div class="spec">我是盒子</div>
<div class="spec">我是盒子</div>
<script>
var spec_divs = document.getElementsByClassName('spec');
</script>

注意事项

  • getElementsByClassName()方法从IE9开始兼容
  • 某个节点元素也可以调用getElementsByClassName()方法 ,从而得到其内部的某类名的元素节点

querySelector()#

querySelector()方法的功能是通过选择器得到元素

<div id="box1">
<p>我是段落</p>
<p class="spec">我是段落</p>
<p>我是段落</p>
</div>
<script>
var the_p = document.querySelector('#box1 .spec');
</script>

注意事项

  • querySelector()方法只能得到页面上一个元素,如果有多 个元素符合条件,则只能得到第一个元素
  • querySelector()方法从IE8开始兼容,但从IE9开始支持 CSS3的选择器,如()、:[src^= ‘dog’]等CSS3选 择器形式都支持良好

querySelectorAll()#

  • querySelectorAll()方法的功能是通过选择器得到元素数组
  • 即使页面上只有一个符合选择器的节点,也将得到长度为1 的数组

节点的关系#

关系考虑所有节点
子节点childNodes
父节点parentNode
第一个子节点firstChild
最后一个子节点lastChild
前一个兄弟节点previousSibling
后一个兄弟节点nextSibling

注意:文本节点也属于节点

  • DOM中,文本节点也属于节点,在使用节点的关系时一定 要注意
  • 在标准的W3C规范中,空白文本节点也应该算作节点,但 是在IE8及以前的浏览器中会有一定的兼容问题,它们不把 空文本节点当做节点

排除文本节点的干扰

  • 从IE9开始支持一些“只考虑元素节点”的属性

    关系考虑所有节点只考虑元素节点
    子节点childNodeschildren
    父节点parentNodeparentElement
    第一个子节点firstChildfirstElementChild
    最后一个子节点lastChildlastElementChild
    前一个兄弟节点previousSiblingpreviousElementSibling
    后一个兄弟节点nextSiblingnextElementSibling

封装节点关系函数#

书写常见的节点关系函数

  • 书写IE6也能兼容的“寻找所有元素子节点”函数

  • 书写IE6也能兼容的“寻找前一个元素兄弟节点”函数

  • 如何编写函数,获得某元素的所有的兄弟节点?

    <body>
    <div id="box">
    <p>我是段落A</p>
    <p id="para">我是段落B</p>
    <p>我是段落C</p>
    </div>
    <script>
    var box = document.getElementById("box");
    var para = document.getElementById("para");
    function getChildren(node) {
    var children = [];//结果数组
    //遍历node的所有子元素
    for (var i = 0; i < node.childNodes.length; i++) {
    //判断是否是元素节点
    if (node.childNodes[i].nodeType === 1) {
    children.push(node.childNodes[i]);
    }
    }
    return children;
    }
    console.log(getChildren(box));
    console.log(getChildren(para));
    function getElementPrevSibling(node) {
    var o = node;
    while(o.previousSibling != null){
    if(o.previousSibling.nodeType === 1){
    return o.previousSibling;
    }
    o = o.previousSibling;
    }
    }
    console.log(getElementPrevSibling(para));
    function getAllElementSibling(node) {
    var prevs = [];
    var nexts = [];
    var o = node;
    while (o.previousSibling != null) {
    if (o.previousSibling.nodeType === 1) {
    prevs.unshift(o.previousSibling);
    }
    o = o.previousSibling;
    }
    o = node;
    while (o.nextElementSibling != null) {
    if (o.nextElementSibling.nodeType === 1) {
    nexts.push(o.nextElementSibling);
    }
    o = o.nextElementSibling;
    }
    return prevs.concat(nexts);
    }
    console.log(getAllElementSibling(para));
    </script>
    </body>

哪些情况需要封装?

场景是否需要封装
获取父元素不需要
获取子元素不需要
获取兄弟元素不需要
获取第一个或最后一个子元素不需要
查找符合条件的祖先元素不需要
实现复杂的节点查找逻辑可以封装
多处重复相同的 DOM 操作可以封装
兼容 IE 等旧浏览器视需求而定

节点操作#

如何改变元素节点的CSS样式

  • 改变元素节点的CSS样式需要使用这样的语句

    oBox.style.backgroundColor ='red';//CSS属性要写成“驼峰”形式
    oBox.style.backgroundImage ='url(images/1.jpg)';//CSS属性值要设置成完整形式
    oBox.style.fontSize ='32px';//注意写单位

如何改变元素节点的HTML属性

  • 标准W3C属性,如src、href等等,只需要直接打点进行更改即可

    oImg.src = 'images/2.jpg';
  • 不符合W3C标准的属性,要使用setAttribute()和getAttribute() 来设置、读取

    oBox.setAttribute('data-n', 10);
    var n = oBox.getAttribute('data-n');
    alert(n);

innerHTML&innerText#

如何改变元素节点中的内容

  • 改变元素节点中的内容可以使用两个相关属性:①innerHTML ② innerText
  • innerHTML属性能以HTML语法设置节点中的内容
  • innerText属性只能以纯文本的形式设置节点中的内容

节点的创建、移除和克隆#

节点的创建

  • document.createElement() 方法用于创建一个指定tag name的HTML元素

    var oDiv = document.createElement('div');

孤儿节点

  • 新创建出的节点是“孤儿节点”,这意味着它并没有被挂载 到DOM树上,我们无法看见它
  • 必须继续使用appendChild()或insertBefore()方法将孤儿 节点插入到DOM树上

appendChild()

  • 追加节点

  • 任何已经在DOM树上的节点,都可以调用appendChild() 方法,它可以将孤儿节点挂载到它的内部,成为它的最后一 个子节点

    父节点.appendChild(孤儿节点);

insertBefore()

  • 任何已经在DOM树上的节点,都可以调用insertBefore() 方法,它可以将孤儿节点挂载到它的内部,成为它的“标杆 子节点”之前的节点

    父节点.insertBefore(孤儿节点, 标杆节点);

示例:

请动态创建出一个20行12列的表格

function createTable() {
var table = document.createElement("table");
for (var i = 0; i < 20; i++) {
var row = document.createElement("tr");
for (var j = 0; j < 12; j++) {
var cell = document.createElement("td");
cell.innerHTML = i + "-" + j;
row.appendChild(cell);
}
table.appendChild(row);
}
document.body.appendChild(table);
}
createTable();

请制作九九乘法表(可以在刚才代码基础上改动升级)

//制作九九乘法表
function createTable1() {
var table = document.createElement("table");
for (var i = 1; i <= 9; i++) {
var row = document.createElement("tr");
for (var j = 1; j <= i; j++) {
var cell = document.createElement("td");
cell.innerHTML = i + "x" + j + "=" + i * j;
row.appendChild(cell);
}
table.appendChild(row);
}
document.body.appendChild(table);
}
createTable1();

移动节点

  • 如果将已经挂载到DOM树上的节点成为appendChild()或者 insertBefore()的参数,这个节点将会被移动

    新父节点.appendChild(已经有父亲的节点);
    新父节点.insertBefore(已经有父亲的节点, 标杆子节点);
  • 这意味着一个节点不能同时位于DOM树的两个位置

删除节点

  • removeChild() 方法从DOM中删除一个子节点

    父节点.removeChild(要删除子节点);
  • 节点不能主动删除自己,必须由父节点删除它

克隆节点

  • cloneNode() 方法可以克隆节点,克隆出的节点是“孤儿节 点

    var 孤儿节点 = 老节点.cloneNode();
    var 孤儿节点 = 老节点.cloneNode(true);
  • 参数是一个布尔值,表示是否采用深度克隆:如果为true,则 该节点的所有后代节点也都会被克隆,如果为false,则只克 隆该节点本身

拓展-延迟执行#

  • 在测试DOM代码时,通常JS代码一定要写到HTML节点的 后面,否则JS无法找到相应HTML节点
  • 可以使用window.onload = function(){} 事件,使页面加 载完毕后,再执行指定的代码

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

JavaScript的DOM之节点
https://f.youzi177.cn/posts/2026102002javascript-de-dom-zhi-jie-dian/
作者
小封鸭
发布于
2026-10-20
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
小封鸭
小楼一夜听春雨,深巷明朝卖杏花
公告
欢迎来到我的博客。这里主要记录前端全栈和日常内容
分类
标签
最新动态
站点统计
文章
60
分类
3
标签
12
总字数
107,734
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录