前面聊了一些对属性的一些操作,当然js也可以对元素的添加删除,毕竟在网页中很多的页面元素需要根据后台返回的数据而呈现的。
当然先聊一下通过元素层级关系得到元素之前的节点。
节点
这个前面说过现在再重复一遍,网页中所有的内容都是节点(标签,属性,文本,注释等),在DOM中节点都是node来表示。
节点和元素区别
这个节点其实很元素区别很大下面进行演示,当然会使用的一些层级关系的方法,下面会具体说,现在主要了解元素和节点的区别。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
*{
margin: 0px;
padding: 0px;
}
div{
width: 400px;
margin: 10px auto;
}
li{
list-style: none;
float: left;
padding: 10px;
background-color: grey;
border-bottom: 1px solid red;
cursor: pointer;
}
.current{
background-color: red;
}
.clearfix:after{
display: block;
content: "";
clear: both;
}
</style>
</head>
<body>
<div class="tap clearfix">
<ul id="test1">
<!-- 这是一个注释-->
<li class="current">商品介绍</li>
<li>规格包装</li>
<li>售后保障</li>
<li>商品评价(100w)</li>
</ul>
</div>
<hr>
<div id="tap clearfix">
<ul id="test2">
<!-- 这是一个注释--><li class="current">商品介绍</li><li>规格包装</li><li>售后保障</li><li>商品评价(100w)</li>
</ul>
</div>
<script>
<!--这个地方会使用一些层级的得到元素和节点的方法,具体后面聊,现在演示一些节点是元素的区别-->
var elements_u1=document.getElementById("test1");
var elements_u2=document.getElementById("test2");
console.log("-----------元素测试----------------");
// 首先得到自元素
var elements_child1 = elements_u1.children;
var len=elements_child1.length;
for(var i=0;i<len;i++){
console.log("第一个ul中的第",i,"个元素是: ",elements_child1[i]);
}
var elements_child2 = elements_u2.children;
var len=elements_child2.length;
for(var i=0;i<len;i++){
console.log("第二个ul中的第",i,"个元素是: ",elements_child2[i]);
}
console.log("-----------节点测试----------------");
var ndoes_child1 = elements_u1.childNodes;
var len=ndoes_child1.length;
for(var i=0;i<len;i++){
console.log("第一个ul中的第",i,"个节点是: ",ndoes_child1[i]);
}
var ndoes_child2 = elements_u2.childNodes;
var len=ndoes_child2.length;
for(var i=0;i<len;i++){
console.log("第二个ul中的第",i,"个节点是: ",ndoes_child2[i]);
}
</script>
</body>
</html>
看一下控制台的输出:
元素的话li元素和注释换不换行没有什么区别,但是节点就不一样,其中最神奇的是为什么节点有#text
是什么意思?
其实这个很容易理解,在元素之间之间可以输入文字的,换行符其实也是一个文本的输入的内容,注释自然也算。所以可以看出元素和节点的区别了。
节点一般至少拥有过三个基本属性nodeType(节点类型),nodeName(节点名称),nodeValue(节点值)
;
其中最常用的一个属性是nodeType:
- 元素节点nodeType的值为1
- 属性节点nodeType的值为2
- 文本节点nodeType的值为3(文本节点包括文字,空格,换行等)
- 注释节点nodeType的值为8
- 文档节点nodeType的值为9
nodeName属性是节点名称是只读属性:
- 元素节点nodeName的值:标签名相同
- 属性节点nodeName的值:属性的名称
- 文本节点nodeName的值:永远是#text
- 注释节点nodeName的值: #comment
- 文档节点nodeName的值:#document
nodeValue属性的值:
- 元素节点nodeValue的值:undefined或者null
- 属性节点nodeValue的值:属性的值
- 文本节点nodeValue的值:文本的内容
- 注释节点nodeValue的值: 注释的内容
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
*{
margin: 0px;
padding: 0px;
}
div{
width: 400px;
margin: 10px auto;
}
li{
list-style: none;
float: left;
padding: 10px;
background-color: grey;
border-bottom: 1px solid red;
cursor: pointer;
}
.current{
background-color: red;
}
.clearfix:after{
display: block;
content: "";
clear: both;
}
</style>
</head>
<body>
<div class="tap clearfix">
<ul id="test1">
<!-- 这是一个注释-->
<li class="current">商品介绍</li>
<li>规格包装</li>
<li>售后保障</li>
<li>商品评价(100w)</li>
</ul>
</div>
<script>
<!--这个地方会使用一些层级的得到元素和节点的方法,具体后面聊,现在演示一些节点是元素的区别-->
var elements_u1=document.getElementById("test1");
console.log("-----------节点测试----------------" );
// 得到属性节点
var attrinode=elements_u1.getAttributeNode("id")
console.log("-----------ul属性节点----------------",elements_u1.getAttributeNode("id"));
console.log("-----------ul属性节点----------------属性节点nodeName是: ",attrinode.nodeName);
console.log("-----------ul属性节点----------------属性节点nodeValue是: ",attrinode.nodeValue);
console.log(" -----------ul属性节点---------------属性节点nodeType是: ",attrinode.nodeType);
var ndoes_child1 = elements_u1.childNodes;
var len=ndoes_child1.length;
for(var i=0;i<len;i++){
console.log("第一个ul中的第",i,"个节点是: ",ndoes_child1[i]);
console.log(" 第",i,"个节点nodeName是: ",ndoes_child1[i].nodeName);
console.log(" 第",i,"个节点nodeValue是: ",ndoes_child1[i].nodeValue);
console.log(" 第",i,"个节点nodeType是: ",ndoes_child1[i].nodeType);
}
</script>
</body>
</html>
结果:
层级元素-得到元素
前面元素是通过id,tap等得到元素,虽然可以得到元素,但是无法在js中了解元素之间的层级关系。而层级关系是什么?
简单的说就是父子,兄弟关系。这样得到的元素人,然后很容易理解元素之间的关系。
父级节点或元素
得到父级节点格式如下:
node.parentNode // 返回父类节点
element.parentElement //返回的是父类元素标签
- parentNode可返回某节点的父节点,注意是最近的一个父节点,如果指定的节点没有父节点就返回null。
- parentElement返回父类元素标签,如果没有返回null
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
*{
margin: 0px;
padding: 0px;
}
div{
width: 400px;
margin: 10px auto;
}
li{
list-style: none;
float: left;
padding: 10px;
background-color: grey;
border-bottom: 1px solid red;
cursor: pointer;
}
.current{
background-color: red;
}
.clearfix:after{
display: block;
content: "";
clear: both;
}
</style>
</head>
<body>
<div class="tap clearfix">
<ul id="test1">
<!-- 这是一个注释-->
<li id="current">商品介绍</li>
<li>规格包装</li>
<li>售后保障</li>
<li>商品评价(100w)</li>
</ul>
</div>
<script>
var elements_l1=document.querySelector("#current")
console.log(elements_l1.parentNode);
elements_l1=document.getElementById("current")
console.log(elements_l1.parentElement);
</script>
</body>
</html>
因为无论父节点还是父元素都是一个元素,所以两者一样。
子元素或子节点
这个是得到元素或节点的子元素或者节点,格式如下:
node.childNodes // 返回子类节点 没有
element.children //返回的是子类元素标签
这两个其实在前面演示节点和元素的区别的时候使用了,可以翻看一下上面。
补充得到第一个或者最后一个子节点或元素
在得到子元素后者节点的时候,还有两个自带的方法可以得到第一个和最后一个子元素或者子节点。
node.firstChild // 返回第一个子类节点
element.firstElementChild //返回的是第一个子类元素标签
node.lastChild // 返回最后一个子类节点
element.lastElementChild //返回的是最后一个子类元素标签
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
*{
margin: 0px;
padding: 0px;
}
div{
width: 400px;
margin: 10px auto;
}
li{
list-style: none;
float: left;
padding: 10px;
background-color: grey;
border-bottom: 1px solid red;
cursor: pointer;
}
.current{
background-color: red;
}
.clearfix:after{
display: block;
content: "";
clear: both;
}
</style>
</head>
<body>
<div class="tap clearfix">
<ul id="test1">
<!-- 这是一个注释-->
<li id="current">商品介绍</li>
<li>规格包装</li>
<li>售后保障</li>
<li>商品评价(100w)</li>
</ul>
</div>
<script>
var elements_l1=document.querySelector("#test1")
console.log("得到节点----------");
console.log(elements_l1.firstChild);
console.log(elements_l1.lastChild);
console.log("得到元素----------");
elements_l1=document.getElementById("test1")
console.log(elements_l1.lastElementChild);
console.log(elements_l1.lastElementChild);
</script>
</body>
</html>
例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
*{
margin: 0px;
padding: 0px;
}
div{
width: 400px;
margin: 10px auto;
}
li{
list-style: none;
}
.tab_list{
float: left;
width: 100px;
padding: 10px;
text-align: center;
background-color: grey;
border-bottom: 1px solid red;
cursor: pointer;
}
.tab_list ul{
margin-top: 20px;
}
.clearfix:after{
display: block;
content: "";
clear: both;
}
a{
text-decoration: none;
color: #cccccc;
}
</style>
</head>
<body>
<div class="tap clearfix">
<ul id="test1">
<!-- 这是一个注释-->
<li class="tab_list">
<a href="#"> 魂类游戏</a>
<ul style="display: none">
<li><a href="#"> 黑魂系列</a></li>
<li><a href="#"> 支狼</a></li>
<li><a href="#"> 仁王</a></li>
<li><a href="#"> 艾尔登法环</a></li>
</ul>
</li>
<li class="tab_list">
<a href="#"> 角色扮演游戏</a>
<ul style="display: none">
<li><a href="#"> 巫师系列</a></li>
<li><a href="#"> 神秘海域系列</a></li>
<li><a href="#"> 消逝的光芒系列</a></li>
<li><a href="#">瘟疫系列 </a></li>
</ul>
</li>
</ul>
</div>
<script>
var li_list=document.getElementsByClassName("tab_list");
var len=li_list.length;
for(var i=0;i<len;i++){
li_list[i].onmouseover=function () {
console.log(this);
this.children[1].style.display="block";
}
li_list[i].onmouseout=function () {
console.log(this );
this.children[1].style.display="none";
}
}
</script>
</body>
</html>
兄弟节点或元素
这个就是在同一个层级的元素,这个兄弟元素主要分前后。
格式:
// 返回当前元素的下一个兄弟节点,找不到返回null
node.nextSibling
// 返回当前元素的上一个兄弟节点,找不到返回null
node.previousSibling
//返回当前元素的下一个兄弟元素,找不到返回null
element.nextElementSibling
//返回当前元素的上一个兄弟元素,找不到返回null
element.previousElementSibling
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
*{
margin: 0px;
padding: 0px;
}
div{
width: 400px;
margin: 10px auto;
}
li{
list-style: none;
}
.tab_list{
float: left;
width: 100px;
padding: 10px;
text-align: center;
background-color: grey;
border-bottom: 1px solid red;
cursor: pointer;
}
.tab_list ul{
margin-top: 20px;
}
.clearfix:after{
display: block;
content: "";
clear: both;
}
a{
text-decoration: none;
color: #cccccc;
}
</style>
</head>
<body>
<div class="tap clearfix">
<ul id="test1">
<li><a href="#"> 黑魂系列</a></li>
<li><a href="#"> 支狼</a></li>
<li><a href="#"> 仁王</a></li>
<li><a href="#"> 艾尔登法环</a></li>
</ul>
</div>
<script>
var element_ul=document.getElementById("test1");
var element_li= element_ul.children(1);
console.log('---元素---')
console.log(element_li.previousSibling)
console.log(element_li.nextSibling)
console.log('---标签---')
console.log(element_li.previousElementSibling)
console.log(element_li.nextElementSibling)
</script>
</body>
</html>
创建元素以及添加元素
创建元素或节点
创建的格式:
document.createElement('标签')
- Document.createElement() 方法用于创建一个由标签名称 tagName 指定的 HTML 元素。如果用户代理无法识别 tagName,则会生成一个未知 HTML 元素 HTMLUnknownElement。
如果单独创建一个元素的,而不将添加道某个元素下,其实没有什么效果的。演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
</head>
<body>
<div >
<ul id="test1">
</ul>
</div>
<script>
var li_element=document.createElement("li");
</script>
</body>
</html>
所以下面聊一下添加元素或者说将其添加到某个元素下面。
添加元素
格式:
//添加元素
element.appendChild(元素或者节点);
// 添加节点
element.append(节点(非属性节点)); // 添加属性节点的时候用 ul_element1.setAttributeNode()
- 添加元素
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
</head>
<body>
<div >
<ul id="test1">
<li>ABC</li>
</ul>
</div>
<script>
var li_element1=document.createElement("li");
var li_element2=document.createElement("li");
var ul_element1=document.getElementById("test1");
var str1="test1";
var str2="test2";
//元素添加这样写文本元素
var str_node= document.createTextNode(str2);
ul_element1.appendChild(li_element1);
ul_element1.appendChild(li_element2);
// 可见这样是无法添加文本的其谁能添加元素
ul_element1.appendChild(str_node);
// 添加一次后,如果再添加别处就会最后一个添加位置生效
ul_element1.appendChild(li_element1);
// 这个地方不会生效的, 如果这样放在后面的编程也会无法运行
console.log("start");
ul_element1.appendChild(str1);
console.log("end")
</script>
</body>
</html>
- 添加节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
</head>
<body>
<div >
<ul id="test1">
<li>ABC</li>
</ul>
</div>
<script>
var li_element1=document.createElement("li");
var li_element2=document.createElement("li");
var ul_element1=document.getElementById("test1");
var str1="test1";
var str2="test2";
//当然节点也可以这样写文本元素
var str_node= document.createTextNode(str2);
ul_element1.append(li_element1);
ul_element1.append(li_element2);
// 可见这样是无法添加文本的其谁能添加元素
ul_element1.append(str_node);
// 添加一次后,如果再添加别处就会最后一个添加位置生效
ul_element1.append(li_element1);
// 添加节点的话可以之间添加文本
console.log("start");
ul_element1.append(str1);
console.log("end")
</script>
</body>
</html>
前面两个添加其实可以看出插入位置是插入子元素的尾部或者说是末端。
当然也可以进行添加在某些元素前面格式如下:
parentNode.insertBefore(newNode, referenceNode)
不再演示,其使用过程很类似就不再单一演示,后面会来一个整体演示。
删除元素
当然也可以删除元素,Node.removeChild() 方法从DOM中删除一个子节点。返回删除的节点。格式:
let oldChild = node.removeChild(child);
//OR
element.removeChild(child);
被移除的这个子节点仍然存在于内存中,只是没有添加到当前文档的DOM树中,因此,你还可以把这个节点重新添加回文档中.
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
</head>
<body>
<div >
<ul id="test1">
<li>ABC</li>
test1
</ul>
</div>
<script>
var ul_element1=document.getElementById("test1");
console.log(ul_element1.childNodes)
console.log('------------')
var li_element=document.getElementsByTagName("li")[0];
var shan_li=ul_element1.removeChild(li_element);
console.log("删除的元素 ",shan_li)
// 因为节点删除了一个所以变得2个了
console.log("======= ",ul_element1.childNodes[1])
var shan_text=ul_element1.removeChild(ul_element1.childNodes[1]);
console.log("删除的文本 ",shan_text)
</script>
</body>
</html>
上面的是父类删除子类元素,还有一种方法是元素自己删除自己格式如下:
Element.remove()
Element.remove() 方法,把对象从它所属的 DOM 树中删除。
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
</head>
<body>
<div id="div-01">Here is div-01</div>
<div id="div-02">Here is div-02</div>
<div id="div-03">Here is div-03</div>
<script>
var el = document.getElementById('div-02');
el.remove();
</script>
</body>
</html>
克隆元素
元素当然也可以克隆,格式如下:
node.cloneNode([flag]);
- node.cloneNode返回一个被克隆元素的副本
- flag 默认是false,是浅拷贝,也就是克隆复制节点的本身,如果节点本身有子节点那就不会被拷贝,但是如果是true的话就是可以完全拷贝。
演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
</head>
<body>
<div id="box">
<div class="div">Here is div-01</div>
<div class="div">Here is div-02</div>
<div class="div">Here is div-03</div>
</div>
<script>
var box_element=document.getElementById('box');
var el = document.getElementsByClassName('div')[0];
console.log(el);
box_element.appendChild(el.cloneNode(true))
box_element.appendChild(el.cloneNode())
</script>
</body>
</html>
元素属性本身也是元素自带的,所以不算是子元素,所以可以默认可以拷贝。
案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试文档</title>
<style>
*{
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
#conment_box ,#conment_list_box{
width: 400px;
margin: 10px auto;
}
#conment_list_box{
border-top: 1px solid red;
}
textarea{
resize: none;
width: 360px;
height: 40px;
margin-top: 5px;
margin-left: 40px;
}
button{
margin-top: 5px;
margin-left: 360px;
}
li{
list-style: none;
margin-top: 10px;
}
</style>
</head>
<body>
<div id="conment_box">
<div> <span>输入评论:</span></div>
<div> <textarea id="text_"></textarea></div>
<div> <button onclick="bt_function()" id="bt">发布</button></div>
</div>
<div id="conment_list_box">
<strong>全部评论</strong>
<ul id="conment_list">
<li>
看见大树守卫,我与宫崎老贼不共戴天,半天后真香。<a href="javascript:;">删除</a>
</li>
</ul>
</div>
<script>
var element_text=document.getElementById("text_");
var element_ul=document.getElementById("conment_list");
function bt_function(){
// alert(element_text.value.trim().length);
if(element_text.value.trim().length>0){
var text_value=element_text.value;
var el=document.createElement("li");
el.innerHTML=text_value +'<a href="javascript:;">删除</a>';
// el.innerHTML('<a href="javascript:;">删除</a>')
// console.log(el);
// var a_el=d('')
// //
// el.appendChild(a_el);
var el_first=element_ul.children[0];
element_ul.insertBefore(el,el_first);
element_text.value="";
var a_els=document.getElementsByTagName("a");
console.log(a_els);
var len=a_els.length;
for (var i=0;i<len;i++){
a_els[i].onclick=function () {
this.parentElement.remove();
}
}
}
}
</script>
</body>
</html>