目录
一、概念详解
Document对象的一些方法(如:createElement()、createAttribute()和createTextNode())允许通过JavaScript在页面中创建不同的元素或节点。不过,新的内容必须作为DOM中已存在节点的子节点中。
在 HTML DOM (文档对象模型)中,每个部分都是节点,常见包括以下三种:
- 文档本身是文档节点
- HTML 元素是元素节点
- HTML 元素的属性是属性节点
- HTML 元素内的文本是文本节点
在 HTML DOM 中,Element 对象表示 HTML 元素。
二、元素节点的属性访问
在DOM中通过使用节点属性可以对各节点进行查询,查询节点的名称、类型、节点值、子节点、兄弟节点和父节点等。DOM常用的节点属性,如下所示
//案例HTML代码
<ul id="ulElement" class="ulClass">
<li class="liElement">1</li>
<li class="liElement">2</li>
<li class="liElement">3</li>
</ul>
2.1 访问自身属性节点
| 属性 | 说明 |
| id | 设置或返回元素的 id。 |
| className | 设置或返回元素的 class 属性。 |
| title | 设置或返回元素的 title 属性。 |
| style | 设置或返回元素的 style 属性。 |
| attributes | 返回一个包含元素所有属性的数组 |
最常使用包括id、className还有style三个属性,例子如下:
//JavaScript代码
window.onload = function(){
var ul = document.getElementById("ulElement");
var li = document.getElementsByClassName("liElement");
console.log("ul元素节点的Id = " + ul.id + ",Class = " + ul.className)
ul.style.background = "red"; //修改或添加ul容器的背景颜色
}
2.2 访问相邻兄弟节点
| 属性 | 说明 |
| parentNode | 返回元素的父节点。 |
| firstElementChild | 返回元素的第一个HTML元素子节点 |
| lastElementChild | 返回元素的最后一个HTML元素子节点 |
| previousElementSibling | 返回元素的上一个相邻的HTML元素子节点 |
| nextElementSibling | 返回元素的下一个相邻的HTML元素子节点 |
| children | 返回元素的所有HTML元素子节点 |
| firstChild | 返回元素的第一个子元素。 (包含非HTML元素节点) |
| lastChild | 返回元素的最后一个子元素。 (包含非HTML元素节点) |
| previousSibling | 返回元素上一个相邻的兄弟节点。(包含非HTML元素节点) |
| nextSibling | 返回元素下一个相邻的兄弟节点。(包含非HTML元素节点) |
| childNodes | 返回元素的所有节点 。 (包括非HTML元素节点) |
我通过previousSibling和nextSibling来访问一下 li[1] 的相邻元素节点看一看
var ul = document.getElementById("ulElement");
var li = document.getElementsByClassName("liElement");
console.log(li[1].parentNode) //第2个li元素的父节点:HTMLUListElement
console.log(li[1].previousSibling) //第2个li元素的上一个节点:#text
console.log(li[1].nextSibling) //第2个li元素的下一个节点:#text
三、相邻HTML兄弟节点的获取
从上一个代码实例中可以看到,li[1]列表节点的上一个节点和下一个节点怎么是#text节点呢?不应该是 li[0] 和 li[2] 节点吗?难道previousSibling 和 nextSibling 并不是指向前后相邻节点?
起始并不是这样,我们通过控制台输出 ul 元素的所有子节点来看一看
从控制台输出的子节点可以看到,它虽然输出了三个 li 子节点,但是彼此前后都包含了一个 text文本节点,这是怎么一回事呢?
我们点开 text节点来看看里面所包含的内容。
这个 text 文本节点所包含的内容是回车符号或者说换行,我们可以通过输出它的节点值得知。那么问题来了,它是从那来的?我们回来看一下HTML的结构,可以得知,我们每一行 li元素标签的前头有缩进,后头有换行,所以这个文本节点就是来自这里。
既然知道了问题,那么如何解决问题呢?
第一种方式:手动删除回车换行,相邻子元素不漏一点缝隙。例如:
<body>
<ul id="ulElement" class="ulClass"><li class="liElement">1</li><li class="liElement">2</li><li class="liElement">3</li></ul>
</body>
第二种方式:通过循环判断每一个节点属性是否是文本节点或者通过正则表达式判断节点值是否是空白、回车、缩进字符,任意满足的节点元素将被删除。
for (var i = 0; i < ul.childNodes.length; i ++) {
if (ul.childNodes[i].nodeType === 3 && /^\s+$/.test(ul.childNodes[i].nodeValue)) {
ul.removeChild(ul.childNodes[i]);
}
}
删除了相邻的文本节点之后,我们就可以获取到 li[1] 节点的相邻元素了,但是这种方式比较麻烦。
第三种方式:通过previousElementSibling和nextElementSibling属性获取相邻HTML元素节点
四、元素节点的操作
| 方法 | 说明 |
| appendChild() | 向元素的子节点末尾中插入一个新的节点 |
| insertBefore() | 向指定元素节点的前面插入一个新的节点。语法:insertBefore(newNode,existingNode) |
| removeChild() | 删除元素中指定的子节点 |
| replaceChild() | 替换元素中的子节点。 |
| setAttribute() | 设置或修改元素中的属性 |
| removeAttribute() | 删除元素的指定属性 |
| getAttribute() | 获取元素的指定属性值 |
| isSameNode() | 检查两个元素是否是相同的节点。 |
| hasAttribute() | 查询元素是否拥有指定属性。如果有则返回true,否则返回 false。 |
| getElementsByClassName() | 从元素中查找子节点中和指定类名相同的节点 |
| getElementsByTagName() | 从元素中查找子节点中和标签名相同的节点 |