目录
0x01 DOM树
DOM:文档对象模型
DOM树:html文件是给人看的。html文件被浏览器解析成DOM树,给浏览器看。方便浏览器进行增删改查操作。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM</title>
<script src="1.js"></script>
</head>
<body>
<div>
div1
<p>p1</p>
<p>p1</p>
div1
</div>
</body>
</html>
整个树挂在DOCUMENT对象下。
DOM树由 三种节点组成
- document节点:只有一个
- 标签节点(元素节点):修改页面的样式需要在标签节点处修改,所以我们要找到标签节点
- 文本节点
0x01 获取标签节点的方法
document.getElementById(‘ID名’) 返回这个id的标签节点(对象)
document.getElementsByTagName('标签名') 返回所有这个标签名的元素的集合(对象数组)
document.getElementsByClassName('class名') 返回所有这个class的元素的集合(对象数组)
document.querySelector("css任意选择器") 返回第一个
document.querySelectorAll("css任意选择器") 返回符合的所有
document.documentElement 返回整个document树
document.body 只返回body部分的树
//3种最常用的找标签节点的方法
//1.通过ID来查找,id具有唯一性
var div1=document.getElementById("div1");
//2.通过标签名字来查找
var ps=document.getElementsByTagName("p");//因为p标签有很多个,所以返回一个数组
var p1=ps[0];
//3.通过class来查找
var a=document.getElementsByClassName("p2");
//通过id获得的直接是节点
//通过tag class获得的一定是数组,就算只有一个也是数组
//getElementById只能在document对象下使用
//而getElementByClassName可以在任意标签节点下使用
var h=document.getElementById("div1");
h.getElementsByClassName("p1");
//h是一个标签节点,在该节点下可以使用getElementsByClassName
例如:
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
#tim{
width:200px;
height:200px;
border:1px solid green;
margin:0 auto;
}
</style>
</head>
<body>
<div id="tim" class='new'>
</div>
<script type="text/javascript">
document.getElementById("tim").style.background='red';
document.getElementsByTagName("div")[0].style.background='green';
document.getElementsByClassName("new")[0].style.background='black';
document.querySelector('#tim').style.background='orange';
document.querySelectorAll('div')[0].style.background='green';
console.log(document.documentElement);
console.log(document.body);
</script>
</body>
</html>
0x02 DOM获取子节点
1.childNodes:
返回子节点的集合,是一个数组。它会把换行和空格也当成是文本节点
结果:
如果这样写,返回的数组中就只有两个div了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1"><div>111</div><div>222</div></div>
<script type="text/javascript">
oDiv = document.getElementById('div1');
console.log(oDiv.childNodes);
</script>
</body>
</html>
2.children
返回值是一个数组。只返回标签节点,不返回文本节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1">
<div>111</div>
<div>222</div>
</div>
<script type="text/javascript">
oDiv = document.getElementById('div1');
console.log(oDiv.children);
</script>
</body>
</html>
0x03 获取父节点
1.parentNode
获取当前元素的直接父元素,是w3c的标准
2.parentElement
获取当前元素的直接父元素,是ie的标准
3.offsetParent
获取距离当前节点最近的一个有定位的父节点或祖先节点,没有即为获取body
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id='bigDiv'>
<div id="div1">
<div>111</div>
<div>222</div>
</div>
</div>
<script type="text/javascript">
oDiv = document.getElementById('div1');
console.log(oDiv.parentNode);
console.log(oDiv.parentElement);
console.log(oDiv.offsetParent);
</script>
</body>
</html>
结果:
0x04判断节点类型
nodeType
1为元素节点
3为文本节点(即空格或换行,字符串)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id='bigDiv'>
<div id="div1">
<div>111</div>
<div>222</div>
</div>
</div>
<script type="text/javascript">
oDiv = document.getElementById('div1');
oChilds=oDiv.childNodes;
for(var i=0;i<oChilds.length;i++){
if(oChilds[i].nodeType==1){
console.log("标签节点");
}else{
console.log("文本节点");
}
}
</script>
</body>
</html>
0x05 获取子节点和兄弟节点
1.获取第一个子节点
(1)firstChild
会匹配到空白或者换行的文本节点
(2)fisrtElementChild
不会匹配到空白或者换行的文本节点。只会获取到标签节点(ElementChild元素节点)。
2.获取最后一个子节点
(1)lastChild
会匹配到空白或者换行的文本节点
(2)lastElementChild 不会匹配到空白或换行的文本节点,只获取标签节点。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1">
<div>one</div>
<div>two</div>
<div id='three'>three</div>
<div>four</div>
<div>five</div>
</div>
<script type="text/javascript">
oDiv = document.getElementById('div1');
oThree=document.getElementById('three');
console.log(oDiv.firstChild);
console.log(oDiv.firstElementChild);
console.log(oDiv.lastChild);
console.log(oDiv.lastElementChild);
</script>
</body>
</html>
3.获取兄弟节点
1.获取上一个兄弟节点
(1)previousElementSibling
会匹配空白或者换行的文本节点
(2)previousElementSibling
不会匹配到空白或换行的文本节点,只获取标签节点。
2.获取下一个兄弟节点
(1)nextSibling
会匹配空白或者换行的文本节点
(2) nextElementSibling
不会匹配到空白或换行的文本节点,只获取标签节点。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1">
<div>one</div>
<div>two</div>
<div id='three'>three</div>
<div>four</div>
<div>five</div>
</div>
<script type="text/javascript">
oDiv = document.getElementById('div1');
oThree=document.getElementById('three');
console.log(oThree.previousSibling);
console.log(oThree.previousElementSibling);
console.log(oThree.nextSibling);
console.log(oThree.nextElementSibling);
</script>
</body>
</html>
0x06 元素属性操作的三种方式
第一种:oDiv.style.display="block";
第二中:oDiv.style[display] ="block";
第三种:DOM方式
获取:getAttribute(属性名称)
设置:setAttribute(属性名称)
删除:removeAttribute(属性名称)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<img src="img/1.jpg" class='img' id='img1' dat="我是自定义属性">
<p id='p1'>我是p1</p>
<script type="text/javascript">
//对节点的属性 内容
//修改已经定义的CSS属性
var img1=document.getElementById("img1");
//写在浏览器console里
img1.src="qiuqiu.jpg";
img1.className="修改后的box";
//因为class是js的关键字所以这里用className来代替class
img1.style.width="100px";//CSS样式的修改
//对自定义的属性修改
//获取属性
img1.getAttribute("dat");//获取img1中的自定义属性dat的值
img1.setAttribute("dat1","1111");//设置(添加)属性dat1的值为1111
img1.removeAttribute("dat1");//删除属性dat1
img1.setAttribute("dat1","213");
//如何修改内容
var p1=document.getElementById("p1");
p1.innerHTML="这是修改后p1的内容";//将p1的值替换,替换的值可以是html标签,可以生效
p1.textContent="这是修改后p1的内容";//这种情况下,即使是替换的内容是html标签也是纯文本形式的,无法生效
</script>
</body>
</html>
0x07 DOM节点的创建插入和删除
1.创建并添加DOM元素
- document.createElement('标签名') 创建一个元素节点
- document.createTextNode('内容') 创建一个文本节点
- appendChild(DOM节点) 为某个DOM添加一个子节点,在最后面添加
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id='ullist'>
<li>我是第1个</li>
<li id="Li2">我是第2个</li>
<li>我是第3个</li>
<li>我是第4个</li>
<li>我是第5个</li>
</ul>
<script type="text/javascript">
var oUl=document.getElementById('ullist');
var oLi2=document.getElementById('Li2');
oLi6 = document.createElement('li');
oLi7 = document.createElement('li');
oLi2_5=document.createElement('li');
oLiText=document.createTextNode('我是第7个节点');
oLi6.innerHTML='我是第6个节点';
oLi2_5.innerHTML='我是第2.5个节点';
oLi7.appendChild(oLiText);
oUl.appendChild(oLi6);
oUl.appendChild(oLi7);
oUl.insertBefore(oLi2_5,oLi2);
</script>
</body>
</html>
2.插入元素
insertBefore(新节点,原有节点) 在已有元素前插入
3.删除DOM元素
removeChild(节点) 删除一个节点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="div1">
<div id="div2"></div>
</div>
<script type="text/javascript">
var oDiv=document.getElementById("div1");
//创建一个p标签
var oP=document.createElement("p");
//创建一个文本节点
var oPtxt=document.createTextNode("p的内容");
oP.appendChild(oPtxt);//将该文本节点添加到p标签下
oDiv.appendChild(oP);//将创建的p节点添加到div1中去
//删除节点
//删除div2
var div2=document.getElementById("div2");
div1.removeChild(div2);
//或者自己干掉自己
div2.parentNode.removeChild(div2);
</script>
</body>
</html>
0x08 文档碎片以及文档碎片的作用
document.createDocumentFragment()创建文档碎片节点,是一个虚拟的节点对象
文档碎片存在的意义就是减少页面渲染DOM的次数
文档碎片可以提高DOM操作性能(理论上)
现在的硬件已经足够强大,不像以前的硬件水平了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id='ullist'>
</ul>
<script type="text/javascript">
var oUl=document.getElementById('ullist');
for(var i=0;i<100;i++){
var oLi=document.createElement('li');
oLi.innerHTML="我是第"+i+"个";
oUl.appendChild(oLi);
}
//每次插入,页面都需要重新渲染一遍,故需要渲染100次
var oFrag = document.createDocumentFragment();
for(var i=0;i<100;i++){
var oLi=document.createElement('li');
oLi.innerHTML="我是第"+i+"个";
oFrag.appendChild(oLi);
}
oUl.appendChild(oFrag);
//只需要渲染一次
</script>
</body>
</html>
0x09 实战应用之DOM快速操作表格单元
首先获取到表格,var oTable=document.getElementById('');
获取表头<thead>用oTable.tHead
获取表尾<tfoot>用oTable.tfoot
获取表体<tbody>用oTable.tBodies
获取行的集合:oTable.tBodies[n].rows
获取一行中一格.oTable.tBodies[n].rows[n].cells[n]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<table id='table' border='1'>
<thead>
<tr>
<td>姓名</td>
<td>年龄</td>
<td>身高</td>
</tr>
</thead>
<tfoot>
<tr>
<td>姓名数量</td>
<td>年龄总和</td>
<td>身高总和</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>张三</td>
<td>21</td>
<td>178</td>
</tr>
<tr>
<td>李四</td>
<td>22</td>
<td>178</td>
</tr>
<tr>
<td>王八</td>
<td>21</td>
<td>198</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
var oTable=document.getElementById('table');
console.log(oTable.tBodies[0].rows[0].cells[0].innerHTML);
</script>
</body>
</html>