头部背景图片
小畅的学习笔记 |
小畅的学习笔记 |

DOM详解

作为前端必备知识点,怎么能不会DOM节点操作呢,今天我们来学一下DOM节点操作吧~
学习参考:
https://www.cnblogs.com/yinshuige/p/5812095.html
https://zhuanlan.zhihu.com/p/148070585
https://blog.csdn.net/alex_wen2014/article/details/101962054
https://blog.csdn.net/qq_42127861/article/details/82145842

一、什么是DOM?

DOM就是文档对象模型,是针对于xml但是扩展用于HTML的应用程序编程接口,定义了访问和操作HTML的文档的标准。
文档对象模型( DOM, Document Object Model )主要用于对HTML和XML文档的内容进行操作。DOM描绘了一个层次化的节点树,通过对节点进行操作,实现对文档内容的添加、删除、修改、查找等功能。

DOM树有两种,分别为节点树和元素树。

  • 节点树:把文档中所有的内容都看成树上的节点;
  • 元素树:仅把文档中的所有标签看成树上的节点。

二、DOM的常用方法

1.获取节点

// 通过id号来获取元素,返回一个元素对象
var myElement = document.getElementById(idName) 

// 通过name属性获取id号,返回元素对象数组 
document.getElementsByName(name)  

// 通过class来获取元素,返回元素对象数组
document.getElementsByClassName(className)   

// 通过标签名获取元素,返回元素对象数组
document.getElementsByTagName(tagName) 

//仅返回第一个匹配的元素,不需要兼容IE      
document.querySelector('#idxxx')

//返回所有匹配的元素,querySelectorAll() 不适用于 Internet Explorer 8 及其更早版本。
document.querySelectorAll('.red')[0]

document.querySelectorAll('#idxxx')[0]

document.querySelectorAll("p.intro");

//获取页面中的HTML标签
document.documentElement

//获取页面中的BODY标签
document.body

//获取页面中的所有元素节点的对象集合型
document.all['']

2.获取/设置元素的属性值:

// 括号传入属性名,返回对应属性的属性值
element.getAttribute(attributeName)

// 传入属性名及设置的值
element.setAttribute(attributeName,attributeValue)

3.创建节点Node

// 创建一个html元素,这里以创建h3元素为例
document.createElement("h3")

// 创建一个文本节点;
document.createTextNode(String);

// 创建一个属性节点,这里以创建class属性为例
document.createAttribute("class");

//创建新的注释节点
document.createComment('注释节点');

//创建文档片段节点
document.createDocumentFragment( );

4.增添节点

// 往element内部最后面添加一个节点,参数是节点类型
parent.appendChild(
element/txt/comment/fragment);

// 在element内部的中在existingNode前面插入newNode
parent.insertBefore(newNode,existingNode); 

//给元素增加属性节点
element.setAttributeNode( attributeName );

//给元素增加指定属性,并设定属性值
element.setAttribute( attributeName, attributeValue );
添加文本节点,有两种常见方法:
  1. document.createTextNode(‘新增文本内容’);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h2>创建文本节点</h2>
<button onclick="addText()">创建文本节点</button>
<p></p>
    <script>
        function addText(){
            var element = document.getElementsByTagName('p')[0];
            var txt = document.createTextNode('新增文本内容'); //创建文本节点
            element.appendChild(txt); //添加文本节点
        }
    </script>
</body>
</html>
  1. element.innerHTML=’新增文本内容’; 【推荐】
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<h2>创建文本节点</h2>
<button onclick="addText()">创建文本节点</button>
<p></p>
    <script>
        function addText(){
            var element = document.getElementsByTagName('p')[0];
            element.innerHTML='新增文本内容'; //插入文本内容
        }
    </script>
</body>
</html>

5.删除节点

//删除当前节点下指定的子节点,删除成功返回该被删除的节点,否则返回null
parentNode.removeChild(Node)

//删除具有指定属性名称的属性,无返回值
element.removeAttribute('属性名');

//删除指定属性,返回值为删除的属性
element.removeAttributeNode( attrNode );

6.修改节点

//用新节点替换父节点中已有的子节点
parentNode.replaceChild( newChild, existingChild );

//若原元素已有该节点,此操作能达到修改该属性值的目的
element.setAttributeNode( attributeName );

//若原元素已有该节点,此操作能达到修改该属性值的目的
element.setAttribute( attributeName, attributeValue );

//更改元素属性
document.getElementById(id).style.property = new style
添加属性节点,修改属性值,有两种常见方法:
  1. element.setAttribute( attributeName, attributeValue );
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h2>属性节点</h2>
    <p class="classValue">增添id属性,并修改class属性值</p>
    <script>
        var element = document.getElementsByTagName('p')[0];
        element.setAttribute('id','idValue'); //添加属性节点
        element.setAttribute('class','classNewValue');//修改属性值
    </script>
</body>
</html>
  1. element.setAttributeNode( attributeName );
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h2>属性节点</h2>
    <p class="classValue">增添id属性,并修改class属性值</p>
    <script>
        var element = document.getElementsByTagName('p')[0];
// 添加属性节点
        var attr = document.createAttribute('id');
        attr.value = 'idValue';
        element.setAttributeNode(attr);

// 修改属性值
        var attr = document.createAttribute('class');
        attr.value = 'classNewValue';
        element.setAttributeNode(attr);

    </script>
</body>
</html>

三、DOM常用属性

1.获取当前元素的文本

// 返回元素的所有文本,包括html代码
element.innerHTML

// 返回当前元素的自身及子代所有文本值,只是文本内容,不包括html代码
element.innerText
document.write和innerHTML主要区别:

document.write是直接将内容写入页面的内容流,会导致页面全部重绘,innerHTML将内容写入某个DOM节点,不会导致页面全部重绘

例子一:页面有初始内容,点击页面中的按钮向页面中通过document.write()方法写入内容,会发现原先的初始内容消失了,整个页面只剩下了通过write()方法写入的内容。原因是整个页面进行了重绘

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--初始内容 -->
<button onclick="fun()" >按鈕</button>

<script>
    function fun() {
        document.write("write内容");
    }
</script>

</body>
</html>

举例二:页面有初始内容,在初始内容后面给定一个节点,通过innerHTML向这个节点写内容,初始内容不消失,通过innerHTML新增加的内容准确的显示在节点位置

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!-- 初始内容 -->
<a id="p"></a>


<button οnclick="fun()">按钮</button>


<script>
    function fun() {
    document.getElementById("p").innerHTML="新增加的innerHTML内容";
    }

</script>

</body>
</html>

2.设置当前元素的样式

// 设置元素的样式时使用style
element.style.color="#eea";   
使用 JavaScript 创建动画
<!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()">单击我</button></p> 

<div id ="container">
<div id ="animate"></div>
</div>

<script>
function myMove() {
var elem = document.getElementById("animate");   
var pos = 0;
var 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> 

3.获取当前节点的名称

// 返回当前节点的名称
node.nodeName 

nodeName 属性规定节点的值。

  • 元素节点的 nodeName 是标签名
  • 文本节点的 nodeName 是属性名称
  • 属性节点的 nodeName 是#text

4.获取当前节点的值

// 返回当前节点的值
node.nodeValue 

nodeValue 属性规定节点的值。

  • 元素节点的 nodeValue 是 undefined 或 null
  • 文本节点的 nodeValue 是文本本身
  • 属性节点的 nodeValue 是属性值

5.获取当前节点的节点类型

// 返回节点的类型,数字形式(1-12)
// 常见几个1:元素节点,2:属性节点,3:文本节点。
node.nodeType   

nodeType 属性返回节点的类型。nodeType 是只读的。比较重要的节点类型有:

元素类型 NodeType
元素 1
属性 2
文本 3
注释 8
文档 9
5.1 元素节点、属性节点、文本节点三者关系

元素节点可以拥有类型属性节点、文本节点、注释节点的子节点。
属性节点与文本节点不是一个层面(角度)上的,因为:在旧 DOM 规范中,属性继承自 Node,是一种特殊的节点。但是DOM4 中已废弃这一条,属性不再是节点。
Image3-1.png

5.2 节点标志(只介绍三种最重要的节点)
元素节点 属性节点 文本节点 注释节点 文档节点
NodeType 1 2 3 8 9
NodeName 标签名 属性名称 #text
NodeValue null 属性value 标签中间夹的文本值
5.3 三种节点的获取方法(这里使用jQuery方法)
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="jquery.min.js"></script>
    <script type="text/javascript">
        $(function () {
        //代码
        })
    </script>
</head>
<body>
<ul id="csdn" name="myname">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
</body>
</html>
1. 获取元素节点
//原生写法
var d = document.getElementById("csdn"); 

d–>获取当前元素节点
d.nodeType–>获取nodeType(只读)
d.nodeName–>获取nodeName(只读)
d.nodeValue–>获取nodeValue(无)

// jquery写法
var d = $("ul")

d–>获取所有元素节点
d[0].nodeType–>获取nodeType(只读)
d[0].nodeName–>获取nodeName(只读)
d[0].nodeValue–>获取nodeValue(无)

Image3-2.png

注意:(这时候浏览器也打印出了ul的子节点)

Image3-3.png

其中的text指的是“回车键”

浏览器显示最终结果如下:

Image3-4.png

分析:对于子节点来说,就是childNodes来说,回车键也算一个节点,那么如图所示,就存在四个回车节点3个元素节点(li)

注意:区分children与childNodes:

Image3-5.png

2. 获取属性节点
//原生写法
var d = document.getElementById("csdn").getAttributeNode("id"); 

d–>获取当前属性节点
d.nodeType–>获取nodeType(只读)
d.nodeName–>获取nodeName(只读)
d.nodeValue–>获取nodeValue(无)

// jquery写法 
var d = $("ul")[0].attributes–>获取所有

d–>获取所有属性节点
d[0].nodeType–>获取nodeType(只读)
d[0].nodeName–>获取nodeName(只读)
d[0].nodeValue–>获取nodeValue(无)
d[0].nodeValue="newValue"–>设置新的nodeValue(写)

//之所以在attributes的下标用0是因为attributes是一个json数组,id这个属性就在其attributes[0]这个地方,如果在设置一个class属性,那么class就在attributes[1]这个地方

浏览器显示如下
Image3-6.png

3. 获取文本节点
//原生写法
var d = document.
getElementsByTagName("li")[0].firstChild;  

d–>获取当前文本节点
d.nodeType–>获取nodeType(只读)
d.nodeName–>获取nodeName(只读)
d.nodeValue–>获取nodeValue(无)

//jquery写法 
var d = $("li").first()[0].childNodes–>获取所有

d–>获取所有文本节点
d[0].nodeType–>获取nodeType(只读)
d[0].nodeName–>获取nodeName(只读)
d[0].nodeValue–>获取nodeValue(无)
d[0].nodeValue="newValue"–>设置新的nodeValue(写)


//之所以在childNodes中下标用0,因为childNodes是一个json数组,而此文本节点刚好在其下标为0的地方,即childNodes的第一个元素

浏览器显示如下

Image3-7.png

综上:想要获得属性节点或者文本节点,第一步首先要绑定元素节点,然后再从元素节点向下找其子节点

四、DOM导航

通过 HTML DOM,您能够使用节点关系来导航节点树

节点树中的节点彼此拥有层级关系。我们常用父(parent)、子(child)和同胞(sibling)等术语来描述这些关系。

  • 术语(父、子和同胞,parent、child 以及 sibling)用于描述这些关系。
  • 在节点树中,顶端节点被称为根(根节点)。
  • 每个节点都有父节点,除了根(根节点没有父节点)。
  • 节点能够拥有一定数量的子
  • 同胞(兄弟或姐妹)指的是拥有相同父的节点。
<html>

<head>
    <title>DOM 教程</title>
</head>

<body>
    <h1>DOM 第一课</h1>
    <p>Hello world!</p>
</body>

</html> 

Image4-1.png

通过 JavaScript,您可以使用以下节点属性在节点之间导航:

  • parentNode
  • childNodes[nodenumber]
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling

    1.获取当前元素的父节点

// 返回当前元素的父节点对象
element.parentNode

2.获取当前元素的子节点

// 返回当前元素所有子元素节点对象,只返回HTML节点
element.chlidren

// 返回当前元素多有子节点,包括文本,HTML,属性节点。(回车也会当做一个节点)
element.chilidNodes

// 返回当前元素的第一个子节点对象
element.firstChild

// 返回当前元素的最后一个子节点对象
element.lastChild

3.获取当前元素的同级元素

// 返回当前元素的下一个同级元素 没有就返回null
element.nextSibling

// 返回当前元素上一个同级元素 没有就返回 null
element.previousSibling
Lililich's Blog