Javascript节点
目录
Javascript节点
一、节点概述
二、节点属性
三、获取节点
3.1、获取父节点parentNode
3.2、获取子节点
3.2.1、所有子节点childNodes
3.2.2、子元素节点children
3.2.3、第一个节点firstChild
3.2.4、最后一个节点lastChild
3.3、获取兄弟节点
四、节点操作
4.1、创建节点
4.2、添加节点
4.3、复制节点
4.4、删除节点
4.5、修改节点
五、下拉菜单案例
六、动态生成表格案例
Javascript节点
一、节点概述
网页中的所有内容都是节点(如:标签、属性、文本、注释等),在DOM 中,节点使用 node
来表示。HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)
均可被修改、创建或删除。
二、节点属性
一般来说节点至少拥有 nodeType(节点类型)、nodeName(节点名称)和 nodeValue(节点
值)这三个基本属性。如下表:
示例:
<div id="box" title="我是文本">我是一个文本节点
<!--我是注释-->
</div>
<script>
var div = document.querySelector('#box')
// 每个节点都有三个基本属性:节点名称(nodeName)、节点类型(nodeType)、节点的值(nodeValue)
console.log('nodeName\tnodeType\tnodeValue')
// 1. 文档节点
console.log(document.nodeName + '\t' + document.nodeType + '\t\t\t' + document.nodeValue);
// 2.元素节点
console.log(div.nodeName + '\t\t\t' + div.nodeType + '\t\t\t' + div.nodeValue)
// 3.获取属性节点
var attrNode = div.attributes[0];
console.log(attrNode.nodeName + '\t\t\t' + attrNode.nodeType + '\t\t\t' + attrNode.nodeValue);
// 4.获取文本节点
var content = div.childNodes[0]
console.log(content.nodeName + '\t\t' + content.nodeType + '\t\t\t' + content.nodeValue);
// 5.获取注释节点
var comment = div.childNodes[1];
console.log(comment.nodeName + '\t' + comment.nodeType + '\t\t\t' + comment.nodeValue);
</script>
运行结果:
三、获取节点
3.1、获取父节点parentNode
在 DOM 中,父级节点使用 parentNode 属性来获取。parentNode 属性可返回指定节点最后的一个父节点,如果指定节点没有父节点,则返回 null。
语法为:node.parentNode
示例:
<div class="grandfather">
<div class="father">
<a href="#" class="son">首页</a>
</div>
</div>
<script>
var a = document.querySelector('a')
console.log(a.nodeName + '\t' + a.nodeType);
// 获取父级节点
var f = a.parentNode; // father
console.log(f);
var gf = f.parentNode // grandfather
console.log(gf);
var body = gf.parentNode // body
console.log(body);
var html = body.parentNode // html
console.log(html);
var doc = html.parentNode // document
console.log(doc);
var v = doc.parentNode // null
console.log(v);
</script>
3.2、获取子节点
3.2.1、所有子节点childNodes
通过 childNodes 属性可以获取指定节点的子节点集合,在这些子节点中包括元素节点和文本节
点。
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
<script>
var ul = document.querySelector('ul')
console.log(ul.childNodes);
</script>
运行结果:
如果只想获取其中的元素节点
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
<script>
var ul = document.querySelector('ul')
var childs = ul.childNodes;
for (var i = 0; i < childs.length; i++) {
if (childs[i].nodeType === 3) {
continue;
}
console.log(childs[i]);
}
</script>
3.2.2、子元素节点children
如果想获取子元素节点而不包含文本节点,那么可以使用 children 属性来实现。children 属性
是一个只读属性,是非标准的,但没有兼容器问题。
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
<script>
var ul = document.querySelector('ul')
var childs = ul.children;
console.log(childs);
</script>
3.2.3、第一个节点firstChild
如果想获取指定节点的第一个子节点,可以使用 firstChild 属性,该属性会返回第一个子节点,
如果没有子节点则返回 null,但它也可能返回一个文本节点。
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
<script>
var ul = document.querySelector('ul')
var fc = ul.firstChild;
console.log(fc);
fc = ul.children[0];
console.log(fc);
</script>
注意:这个属性也把换行当作是一个子节点。
3.2.4、最后一个节点lastChild
获取指定节点的最后一个子节点,可以使用 lastChild 属性,该属性会返回第一个子节点,如果
没有子节点则返回 null,但它也可能返回一个文本节点。
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
<script>
var ul = document.querySelector('ul')
var lc = ul.lastChild;
console.log(lc);
lc = ul.children[ul.children.length - 1]; //这种方式可以避免获取文本节点
console.log(lc);
</script>
注意:lastChild 也会把换行当作是子节点。
3.3、获取兄弟节点
使用 nextSibling 属性可以获取指定节点的下一个兄弟节点,找不到就返回 null。而通过
previousSibling 属性可以获取指定节点的前一个兄弟节点,找不到也返回 null。
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
<script>
var firstLi = document.querySelector('li'); //获取第一个li
console.log(firstLi);
// 使用 nextSibling 来获取下一个兄弟节点
var next = firstLi.nextSibling;
console.log(next);
// 使用 nextElementSibling 来获取下一个兄弟节点
next = firstLi.nextElementSibling;
console.log(next);
// 使用 previousSibling 获取前一个兄弟节点
var prev = next.previousSibling;
console.log(prev);
// 使用 previousElementSibling 来获取下一个兄弟节点
prev = next.previousElementSibling;
console.log(prev);
</script>
运行结果:
注意:
(1)nextSibling和previousSiblin都可能返回一个文本节点,并且把换行当作文本节点;
(2)nextElementSibling和previousElementSibling返回的是一个元素节点;
(3)在开发中,经常用nextElementSibling和previousElementSibling来获取兄弟节点。
四、节点操作
4.1、创建节点
创建节点通过 document.createElement('tagName') 语法来创建。targName 是指要创建的
HTML 元素。
var li = document.createElement('li');
这样就创建了一个 li 节点,但该节点只是在内在中创建出来了,还需要通过下面的方法添加到页
面中。
4.2、添加节点
(1)parentNode.appendChild(child):把指定节点添加到指定的父节点的子节点最后;
(2)parentNode.insertBefore(child):把指定节点添加到指定的父节点的指定子节点前面;
(3)parentNode.append(element):把指定的元素添加到指定的父元素的子节点最后,没有返回值;
(4)parentNode.prepend(element):把指定的元素添加到指定的父元素的最前面,没有返回值。
<ul>
<li>北京</li>
</ul>
<script>
//获取父节点
var ul = document.querySelector('ul');
// 1
// 创建节点通过 document.createElement('tagName'); 执行后会返回这个元素
var li = document.createElement('li');
var text = document.createTextNode('appendChild') // 创建文本节点
li.appendChild(text) //li添加文本节点
// 添加到 ul 节点中
ul.appendChild(li); //ul添加li
// 2
li = document.createElement('li');
li.innerHTML = 'insertBefore';
ul.insertBefore(li, ul.children[1]); //添加到索引号为1的li的前面
// 3
li = document.createElement('li');
li.innerText = 'append'
ul.append(li)
// 4
li = document.createElement('li');
li.innerText = 'prepend'
ul.prepend(li)
</script>
4.3、复制节点
复制节点也叫克隆节点,需要使用 cloneNode() 方法来实现。该方法执行后会返回调用该方法节
点的一个副本。该方法可以传一个布尔类型参数,默认为 false 表示浅拷贝,如果参数为 true 表
示深拷贝。浅拷贝只会复制节点元素,不会复制节点内容。而深拷贝会复制节点以及所有的子节
点。
语法格式:
克隆的副本 = srcNode.cloneNode([false|true]);
示例:
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>
<ul>
<li>重庆</li>
<li>渝北</li>
</ul>
</li>
</ul>
<script>
// 需求:克隆 ul
// 1. 获取被克隆元素
var ul = document.querySelector('ul');
// 2. 调用 cloneNode() 方法进行克隆
var newNode = ul.cloneNode(false);
//console.log(newNode);
// 把新的节点添加到 body 中
document.body.prepend(newNode);
// 3. 深拷贝
newNode = ul.cloneNode(true);
document.body.prepend(newNode);
</script>
4.4、删除节点
删除节点需要使用 removeChild(child) 方法来实现。该方法是从指定节点中删除一个子节
点,并返回被删除的节点。
语法格式:
父级节点.removeChild(子节点);
示例:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
//1、获取元素
var ul = document.querySelector('ul');
// 2、删除元素
ul.removeChild(ul.children[0]);
</script>
4.5、修改节点
修改节点需要使用 replaceChild() 方法,该方法有两个参数,第一个参数是新节点,第二个参数
是被替换的子节点。这个方法执行后,会返回被替换的子节点。
语法格式:
父级节点.replaceChild(新节点, 被替换的子节点);
replaceChild<T extends Node>(node: Node, child: T): T;
示例:
<ul>
<li>北京</li>
<li>上海</li>
<li>天津</li>
<li>重庆</li>
</ul>
<script>
var ul = document.querySelector('ul');
var li = document.createElement('li');
li.innerHTML = '西安';
ul.replaceChild(li, ul.children[0]); //将北京改成西安
//ul.replaceChildren(li, ul.children[0]);
</script>
注意:替换节点还可以使用 replaceChildren() 方法,它的参数是一个可变参数,可以传多
个值,执行后的结果为:原节点中的内容全部被替换为指定的参数列表中的内容。
五、下拉菜单案例
需求:实现京东下拉菜单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>案例</title>
<style>
* {margin: 0; padding: 0;}
li {list-style-type: none;}
a {text-decoration: none; font-size: 14px;}
.menu {margin: 100px;}
.menu>li {
position: relative;
width: 100px;
height: 40px;
text-align: left;
float: left;
}
.menu>li>a {
display: block;
width: 100%;
height: 100%;
line-height: 40px;
color: #333;
padding-left: 5px;
background: #f5f5f5;
}
.menu>li>a:hover {
background-color: #ffffff;
}
.menu ul {
display: none;
position: absolute;
top: 40px;
left: 0;
width: 100%;
}
.menu>li>ul>li a {
display: block;
width: 100%;
height: 100%;
line-height: 40px;
color: #333;
padding-left: 5px;
background: #ffffff;
border: 1px solid #f5f5f5;
border-top: none;
}
.menu ul li a:hover {
background-color: #f5f5f5;
}
</style>
</head>
<body>
<ul class="menu">
<li>
<a href="">我的淘宝</a>
<ul>
<li><a href="">已买到的宝贝</a></li>
<li><a href="">我的足迹</a></li>
</ul>
</li>
<li>
<a href="">收藏夹</a>
<ul>
<li><a href="">收藏的宝贝</a></li>
<li><a href="">收藏的店铺</a></li>
</ul>
</li>
<li>
<a href="">联系客服</a>
<ul>
<li><a href="">消费者客服</a></li>
<li><a href="">卖家客服</a></li>
</ul>
</li>
<li>
<a href="">网站导航</a>
<ul>
<li><a href="">主题市场</a></li>
<li><a href="">特色市场</a></li>
</ul>
</li>
</ul>
<script>
var menu = document.querySelector('.menu')
var lis = menu.children
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function () {
this.children[1].style.display = 'block';
};
lis[i].onmouseout = function () {
this.children[1].style.display = 'none';
};
}
</script>
</body>
</html>
六、动态生成表格案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态生成表格</title>
<style>
table {
width: 500px;
margin: 0 auto;
text-align: center;
border-collapse: collapse;
}
thead tr {
height: 40px;
background-color: rgb(161, 143, 143);
}
td,
th {
border: 1px solid rgb(80, 73, 73);
}
</style>
</head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
//1、先去准备好学生的数据
var datas = [{
name: '李大钊',
subject: 'javaScript',
score: 100
}, {
name: '陈独秀',
subject: 'javaScript',
score: 99
}, {
name: '毛泽东',
subject: 'javaScript',
score: 97
}, {
name: '周恩来',
subject: 'javaScript',
score: 96
}, ];
//2、往tbody里面创建行:有几个人(通过数组的长度)我们就创建几行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
//创建 tr行
var tr = document.createElement('tr');
tbody.appendChild(tr);
//行里面创建单元格 td 单元格的数量取决于每个对象里面的属性个数 for循环遍历对象 datas[i]
for (var k in datas[i]) {
//创建单元格
var td = document.createElement('td');
//把对象里面的属性值 datas[i][k]给td
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
//3、创建有删除2个字的单元格
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除</a>';
tr.appendChild(td);
}
// 4、删除操作
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
tbody.removeChild(this.parentNode.parentNode);
}
}
</script>
</body>
</html>
A6985_: 这不是b站瑞思拜的吗
柠檬果379: 调用的时候才会压入
想你的风吹到了瑞士: 函数是调用的时候压入执行栈还是遇见function就压入
Dnan?2: 多更新,爱看
宇宙无敌大美男: 很详细,但是我登录报:WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store。很烦。不过还是谢谢博主的细心,每一步都看的清清楚楚