目录
一.学习节点操作目的
二.节点概述
三.节点层级
四.创建添加节点
五.删除节点
六.克隆节点
一.学习节点操作目的
我们为什么学习节点操作?学习节点操作的目的是为了获取元素。
在学习节点操作之前,我们已经学习了利用DOM提供的方法获取元素。
如document.getElementById,document.getElementsByClassName 等等 但它存在着逻辑性不强,繁琐的缺点。
我们利用节点层级关系获得元素,逻辑性会更强,操作相对于前者也会更加简单,但也存在着兼容性稍差的缺点。
二.节点概述
在网页中所有内容均为节点(标签,属性,文本,注释等),在DOM中节点用node表示。
HTML DOM树中所有节点均可以通过JavaScript进行访问,所有HTML元素(节点)均可以被修改,创建,或删除。
DOM树:
一般的节点至少拥有nodeType(节点类型),nodeName(节点名称),nodeValue(节点值),这三个基本属性。
- 元素节点nodeType为1(元素节点包括如body,div这样的标签,皆是元素节点)
- 属性节点nodeType为2 (如class="box",这样的属性称为属性节点)
- 文本节点nodeType为3(文本节点包括文字,空格,换行等)
在我们的实际开发中,节点操作的主要是元素节点
三.节点层级
利用DOM树可以把节点划分为不同层级关系,常见的是父子兄层级关系
1.父级节点
node.parentNode
- parentNode可以返回某节点的父级节点,注意是最近的一个父级节点
- 如果指定的节点没有父级节点,就返回null
代码演示:
<div class="demo">
<div class="box">
<span class="erweima">×</span>
</div>
</div>
<script>
// 1.父节点 parentNode
var erweima = document.querySelector('.erweima');
// 得到离元素最近的父级节点
console.log(erweima.parentNode); //就可以得到box
</script>
2.子级节点
(1)parentNode.childNodes,返回包含指定节点子节点的集合,该集合为及时更新的集合。
parentNode.childNodes(标准)
注意:返回值里包含了所有节点,元素节点,文本节点,等等,如果想要单纯获得元素节点,则需要做其他处理,所以我们一般不提倡用parentNode,childNodes获取子节点。
(2)parentNode.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其他元素不返回。(children虽然是非标准的,但得到所有浏览器的支持,没有兼容性的问题)
parentNode.children
(1)(2)代码演示:
<body>
<div>我是div</div>
<span>我是span</span>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ol>
<div class="demo">
<div class="box">
<span class="erweima">×</span>
</div>
</div>
<script>
// DOM提供的方法(API)获取
var ul = document.querySelector('ul');
var lis = document.querySelectorAll('li');
// 1.子节点 childNode包括所有子节点 文本节点 元素节点 等等 (所以我们一般不使用)
console.log(ul.childNodes); //html(9) 因为他们之间是有换行的 换行属于文本节点
console.log(ul.childNodes[0].nodeType);
console.log(ul.childNodes[1].nodeType);
// 2.children获取所有的子元素节点 非正式 较常用
console.log(ul.children);
</script>
</body>
(3)parentNode.firstChild返回第一个子节点,没有则返回null,同样也是包含所有节点
parentNode.firstChild
(4)parentNode.lastChild返回第一个子节点,没有则返回null,同样也是包含所有节点
parentNode.lastChild
(5)parentNode.firstElementChild返回第一个子元素节点,没有则返回null
parentNode.firstElementChild
(6)parentNode.lastElementChild返回第一个子元素节点,没有则返回null
parentNode.lastElementChild
注意:(5) (6)两种方法虽可以直接获得第一个与最后一个子元素节点,但也存在兼容性的问题,只有ie9以上才支持。
(4)~(6)代码演示:
<body>
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ol>
<script>
// 获取第一个子元素与最后一个子元素
var ol = document.querySelector('ol');
// 1.firstChild第一个节点 不管是文本节点还是元素节点
console.log(ol.firstChild);
console.log(ol.lastChild);
// 2.firstElmentChild返回第一个子元素节点 但这个存在兼容性的问题
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
</script>
</body>
在实际开发中firstChild,lastChild只能获取第一个子节点,而firstElementChild,lastElementChild有存在兼容性的问题,那有什么方法可以解决呢?
解决方案:如果想要第一个子元素节点,可以使用parentNode.children[0]
// 3.实际开发的写法 既没有兼容性的问题 又返回第一个元素
console.log(ol.children[0]);
console.log(ol.children[ol.children.length - 1]);
3.兄弟节点
(1)nextSibling 返回下一个兄弟节点 包含元素节点或者文本节点,找不到则返回null
node.nextSibling
(2)previousSibling 返回上一个兄弟节点 包含元素节点或者文本节点,找不到则返回null
node.previousSibling
(3)nextElementSibling 返回下一个兄弟元素节点,找不到则返回null,存在兼容性问题
node.nextElementSibling
(4)previousElementSibling 返回上一个兄弟元素节点 ,找不到则返回null,存在兼容性问题
node.previousElementSibling
注意:如果想解决兼容性问题需要自己封装一个函数
(1)~(4)代码演示:
<body>
<div>1</div>
<span>2</span>
<script>
var div = document.querySelector('div');
// 1.nextSibling 下一个元素节点 包含元素节点或者文本节点
console.log(div.nextSibling);
console.log(div.previousSibling);
// 2.nextElementSibling 获取下一个元素节点
console.log(div.nextElementSibling);
console.log(div.previousElementSibling); //没有的话就是null
</script>
</body>
四.创建添加节点
1.创建节点
document.createElement();方法创建由tagName指定的HTML元素,因为这些元素不存在,是根据我们的需求动态生成的,所以也称为动态创建元素节点。
document.createElement('tagName');
2.添加节点
(1)node.appendChild()方法将一个指定节点添加到父节点的子节点列表末尾,类似于css里面的:after伪元素。
node.appendChild()
(2)node.insertBefore()方法是将一个节点添加到父节点的指定子节点的前面,类似与css里面的:before伪元素。
node.insertBefore(child,指定元素)
代码演示:
<body>
<ul>
<li>123</li>
</ul>
<script>
// 1.创建节点元素
var li = document.createElement('li');
// 2.添加节点 node.appendChild(child); node是父级 child是子级 后面追加元素 类似于数组中的push
// (1)先获取父级元素小li
var ul = document.querySelector('ul');
ul.appendChild(li);
// 3.添加节点 insertBefore(child,指定元素) 指定元素就是要加在它前面的元素
var lili = document.createElement('li'); //括号里面要填创建的元素类型
ul.insertBefore(lili, ul.children[0]); //在第一个li的前面插入lili
// 4.我们想在页面中添加一个元素分两步 1.创建元素 2.添加元素
</script>
</body>
五.删除节点
node.removeChild()方法从DOM中删除一个子节点,返回删除节点
node.removeChild()
代码演示:
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<button>删除</button>
<script>
// 1.获取元素
var btn = document.querySelector('button');
var ul = document.querySelector('ul');
// 2.删除元素 node.removeChild(child);
// ul.removeChild(ul.children[0]);
// 3.点击按钮依次删除里面的孩子
btn.onclick = function () {
if (ul.children.length == 0) {
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
六.克隆节点
node.cloneNode()返回点用该方法元素节点的一个副本,也称为克隆节点或拷贝节点
node.cloneNode()
注意:
1.node.cloneNode() 如果括号为空或者括号里面为false则为浅拷贝· 浅拷贝只复制标签 不复制标签里面的内容
2.node.cloneNode(true) 括号里面为true则为深拷贝 深拷贝复制标签与标签里面的内容
代码演示:
<body>
<ul>
<li>11111</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
var lili = ul.children[0].cloneNode('true');
ul.appendChild(lili);
</script>
</body>