概述
- 网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
- HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
一般节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
- 元素节点:nodeType 为1
- 属性节点:nodeType 为2
- 文本节点:nodeType 为3(文本节点包括文字、空格、换行等)
节点操作主要操作的是元素节点
1.父级节点
node.parentNode
,node
是子节点,node.parentNode
获取到的就是父节点,如果没有父节点,则返回null
var li1 = document.querySelector('li');
var ul = li.parentNode;//获取ul
2.子结点
1.node.childNodes(标准)
node.childNodes
的返回值包含了所有的子结点,包括元素节点,文本节点- 如果只想要获得里面的元素节点,则需要专门处理,所以一般不提倡使用
childNodes
- 处理方法,
for
循环取nodeType
为 1 的子节点
for (var i = 0; i < ul.childNodes.length; i++) {
if (ul.childNodes[i].nodeType == 1) {
console.log(ul.childNodes[i]);
}
}
2.node.children(非标准)
-
node.children
是一个只读属性,返回所有的子元素节点 - 它只返回子元素节点,其余节点不返回
- 虽然 children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用
3.第一个最后一个子结点(不太好用)
-
firstChild
返回第一个子节点,lastChild
返回最后一个节点,找不到则返回null - 因为返回值可以是任何节点(可能是文本节点),所以不太好用
node.firstChild
node.lastChild
4.第一个最后一个子结点(还行,但也不是最好,因为兼容性不够好)
-
firstElementChild
返回第一个子元素节点,lastElementChild
返回最后一个子元素节点 - 有兼容性问题,IE9以上才支持
node.firstElementChild
node.lastElementChild
5.最常用的方案
- 如果想要第一个子元素节点,可以使用
node.chilren[0]
- 如果想要最后一个子元素节点,用
node.chilren[node.chilren.length - 1]
3.兄弟节点
1.上一个和下一个兄弟节点(不太好用)
-
nextSibling
返回当前元素的下一个兄弟元素节点,previousSibling
返回当前元素上一个兄弟元素节点,找不到则返回null - 因为返回值可以是任何节点(可能是文本节点),所以不太好用
node.nextSibling
node.previousSibling
2.上一个和下一个兄弟节点(还行,但也不是最好,因为兼容性不够好)
-
nextElementSibling
返回当前元素下一个兄弟元素节点,previousElementSibling 返回当前元素上一个兄弟元素节点,找不到则返回null - 有兼容性问题,IE9以上才支持
node.nextElementSibling
node.previousElementSibling
解决方案
自己封装一个函数
function getNextElementSibling(element) {
var el = element;
while(el = el.nextSibling) {
if(el.nodeType === 1){
return el;
}
}
return null;
}
4.增删节点
-
document.createElement()
方法创建由 tagName 指定的HTML 元素 - 因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点
document.createElement('tagName');
1.添加节点
node.appendChild()
方法将一个节点添加到指定父节点的子节点列表末尾。
node.appendChild(child)
node.insertBefore()
方法将一个节点添加到父节点的指定子节点前面。
node.insertBefore(child,指定元素)
//将一个节点添加到父节点的子节点最前面
node.insertBefore(child, node.children[0])
2.删除节点
node.removeChild()
方法删除一个子节点,返回删除的节点
留言板案例
<textarea name="" id="" cols="30" rows="10"></textarea>
<button class="add">提交</button>
<!-- <button class="del">删除</button> -->
<ul></ul>
<script>
var text = document.querySelector('textarea');
var btnadd = document.querySelector('.add');
// var btndel = document.querySelector('.del');
var ul = document.querySelector('ul');
btnadd.onclick = function() {
if (text.value) {//如果文本域不为空
//创建li节点,并在最前面插入
var li = document.createElement('li');
ul.insertBefore(li, ul.children[0])
//给li赋值并 添加删除按钮
li.innerHTML = text.value + '<a href="javascript:;">删除</a>';
//复制之后,让文本域为空
text.value = '';
//给删除按钮添加删除事件
var del = document.querySelector('a');
del.onclick = function() {
ul.removeChild(this.parentNode);
}
}
}
</script>
5.克隆节点
node.cloneNode()
方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点- 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
- 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点
node.cloneNode()
方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点- 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
- 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点