慕课前端入门-DOM
1. DOM
DOM是JS操控html和css的桥梁
html不能使用字符串思维,要使用节点思维。
DOM(Document Object Model,文档对象模型)是Javascript操作html文档的接口,使文档操作变得非常优雅,简便。
DOM最大的特点是将文档表示为节点树。
2.node
2.1 nodeType常用属性值
noteType值 | 节点类型 |
---|---|
1 | 元素节点 |
3 | 文字节点 |
8 | 注释节点 |
9 | document节点 |
10 | DTD节点 |
2.2 访问元素节点
- 所谓访问元素节点,就是指得到、获取页面上的元素节点
- 对节点进行操作,第一步就是要得到它
- 访问元素节点,主要依靠document对象
- document对象是DOM中最重要的东西,几乎所有DOM的功能都封装在了document对象中
- document对象也代表整个html文昌,它是DOM节点树的根
- document对象的noteType属性值是9
方法 | 说明 | 示例 |
---|---|---|
document.getElementById() 通过ID得到元素 |
|
document.getElementById("box1"); |
document.getElementsByTagName() 通过标签名得到元素数组 |
|
document.getElementsByTagName("div"); |
document.getElementsByClassName() 通过类型得到元素数组 |
|
document.getElementByClassName("squar200") |
document.querySelector() 通过选择器得到元素 |
|
document.querySelector('#box p:nth-child(1)'); |
document.querySelectorAll() 通过选择器得到元素数组 |
|
document.querySelectorAll("#list1 li"); |
2.3 节点的关系
关系 | 考虑所有节点 | 只考虑元素节点 |
子节点 | childNodes | children |
父节点 | parentNode | 相同 |
第一个子节点 | firstChild | firstElementChild |
最后一个子节点 | lastChild | lastElementChild |
前一个子节点 | previousSibling | previousElementSibling |
后一个子节点 | nextSibling | nextElementSibling |
注意:文本节点也属于节点。在标准的W3C规范中,空白文本节点也应该算作节点。但是在IE8及以前的浏览器中会有一定的兼容性问题,它们不把空白文本节点当作节点。
排除文本节点的干扰,从IE9开始支持一些只考虑元素节点的属性
示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cartoon Dog</title>
</head>
<body>
<div id="box">
<p>我是段落A</p>
<p id="para">我是段落B</p>
<p>我是段落C</p>
</div>
</body>
</html>
<script type="text/javascript">
var box = document.getElementById("box");
var para = document.getElementById("para");
//所有子节点
console.log(box.childNodes);
//所有元素子节点
console.log(box.children);
//第一个子节点
console.log(box.firstChild);
//第一个元素子节点
console.log(box.firstElementChild);
//最后一个子节点
console.log(box.lastChild);
//最后一个元素子节点
console.log(box.lastElementChild);
//前一个兄弟节点
console.log(para.previousSibling);
//前一个兄弟元素子节点
console.log(para.previousElementSibling);
//后一个兄弟节点
console.log(para.nextSibling);
//后一个兄弟元素子节点
console.log(para.nextElementSibling);
//父节点
console.log(para.parentNode);
</script>
2.4 书写常见的节点关系函数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cartoon Dog</title>
</head>
<body>
<div id="box">
<p>我是段落A</p>
<p id="para">我是段落B
<span>1</span>
<span>2</span>
<span>3</span>
</p>
<p>我是段落C</p>
</div>
</body>
</html>
<script type="text/javascript">
var box = document.getElementById("box");
var para = document.getElementById("para");
//封装一个函数,这个函数可以返回元素的所有元素子元素节点(兼容到IE6),类似children的功能
function getChildren(node){
//结果数组
var children = []
//遍历node这个节点的所有子节点,判断每一个子节点的nodeType是不是1
//如果是1,就推入结果数组
for(var i=0;i<node.childNodes.length;i++){
if(node.childNodes[i].nodeType == 1){
children.push(node.childNodes[i]);
}
}
return children;
}
console.log(getChildren(box));
//封装一个函数,这个函数可以返回元素的前一个兄弟元素节点(),类似previousElementSibling的功能
function getPreElementSibling(node){
var thisNode = node;
//使用while语句
while(thisNode.previousSibling != null){
if(thisNode.previousSibling.nodeType ==1){
//结束循环
return thisNode.previousSibling;
}
//对前一个节点,继续查找
thisNode = thisNode.previousSibling;
}
return null;
}
console.log(getPreElementSibling(para));
//封装第三个函数,这个函数有可以返回元素的所有兄弟节点
function getAllElmentSibling(node){
var result=[],allNode = getChildren(node.parentNode);
for(var i=0;i<allNode.length;i++){
if(allNode[i]==node){
continue;
}
result.push(allNode[i]);
}
return result;
}
console.log(getAllElmentSibling(para));
</script>
2.5 节点操作
改变元素节点中的内容,可以使用两个相关属性:
- innerHTML属性能以HTML语法设置节点中的内容
- innerText属性只能以纯文本的形式,设置节点中的内容
功能 | 方法 |
改变元素节点的内容 | innerHTML属性能以html语法加载 innerText属性只能以纯文本的形式设置节点中的内容 |
改变元素节点的CSS样式 | elment.style.backgrounColor="red"; |
改变元素节点的HTML属性 | 标准W3C属性 labu.src="images/0.jpg"; 不符合W3C标准的属性 box1.setAttribute("data-n",10); box1.getAttribute("data-n"); |
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
.wind{float: left;overflow: hidden;}
.box{width: 200px;height: 200px;border: 1px solid #000;}
.clear{clear: both;}
</style>
</head>
<body>
<div id="box1" class="box wind"></div>
<div id="box2" class="wind">
<p id="desc">这是一条狗</p>
<img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=311752711,1581170649&fm=26&gp=0.jpg" id="labu">
</div>
<div class="clear"></div>
</body>
</html>
<script type="text/javascript">
//改变元素节点中的内容
var box1 = document.getElementById("box1");
var descOn2 = document.getElementById("desc");
descOn2.innerText="慕课网";
box1.innerHTML="<ul><li>牛奶</li><li>咖啡</li></ul>";
//改变元素节点的CSS样式
box1.style.backgroundColor="red";
//标准W3C属性
var labu = document.getElementById("labu");
labu.src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=155346741,3953923104&fm=26&gp=0.jpg";
//不符合W3C标准的属性
box1.setAttribute("data-n",10);
console.log(box1.getAttribute("data-n"));
</script>
2.6 节点的创建
功能 | 说明 |
创建节点 document.createElement() | 用于创建一个指定标签的元素 新创建的节点是孤儿节点,这意味着它并没有被挂载到DOM树上,页面上不可见。 必需继续使用appendChild() insertBefore()将孤儿节点挂在到它的内部 |
添加节点 父节点.appendChild(孤儿节点) | 任何已经在DOM树上的节点,都可以调用appendChild, 将孤儿节点挂载到它的内部,成为它的最后一个子节点。 |
插入节点 父节点.insertBefore(孤儿节点, 标杆节点) | 任何已经在DOM树上的节点,都可以调用insertBefore, 将孤儿节点挂载到它的内部,成为它的标杆子节点之前的节点。 |
示例
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
div{width: 200px;height: 200px;border: 1px solid red;margin: 10px;}
</style>
</head>
<body>
<div id="box1">
<p>我是原本的段落0</p>
<p>我是原本的段落1</p>
<p>我是原本的段落2</p>
</div>
<div id="box2">
<p>我是原本的段落0</p>
<p>我是原本的段落1</p>
<p>我是原本的段落2</p>
</div>
</body>
</html>
<script type="text/javascript">
var obox1 = document.getElementById('box1');
var obox2 = document.getElementById('box1');
var ops2 = obox2.getElementsByTagName("p");
//创建孤儿节点
var op1 = document.createElement('p');
op1.innerText="我是新来的";
//上树
obox1.appendChild(op1);
//创建孤儿节点
var op2 = document.createElement('p');
op2.innerText="插个队";
obox2.insertBefore(op2,ops2[2]);
</script>
示例:使用节点创建一个20行12列的表格
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
td{width: 10px;height: 10px;}
</style>
</head>
<body>
<table id="table" border="1" ></table>
</body>
</html>
<script type="text/javascript">
var snode = document.getElementById("table");
for(var i=0;i<20;i++){
var tr = document.createElement("tr");
for(var j=0;j<12;j++){
var td = document.createElement("td");
tr.appendChild(td);
}
console.log(tr);
snode.appendChild(tr);
}
</script>
示例:制作九九乘法表
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
td{padding: 5px 10px;border: 1px solid #000;}
</style>
</head>
<body>
<table id="table" ></table>
</body>
</html>
<script type="text/javascript">
var snode = document.getElementById("table");
for(var i=1;i<10;i++){
var tr = document.createElement("tr");
for(var j=1;j<=i;j++){
var td = document.createElement("td");
td.innerText = j+"x"+i+"="+i*j;
tr.appendChild(td);
}
console.log(tr);
snode.appendChild(tr);
}
</script>
2.7 节点的移动
移动节点方法同创建节点,移动节点意味着一个节点不能同时位于DOM树的两个位置。
父节点.appendChild(节点)
父节点.insertBefore(节点, 标杆子节点);
<ul id="ul1">
<li>我是ul1的li</li>
<li id="li12">我是ul1的li</li>
<li id="li13">我是ul1的li</li>
<li>我是ul1的li</li>
</ul>
<ul id="ul2">合资
<li>我是ul2的li</li>
<li>我是ul2的li</li>
<li id="li23">我是ul2的li</li>
</body>
</h
<script type="text/javascript">
var ul1 = document.getElementById("ul1");
var li12 = document.getElementById("li12");
var li13 = document.getElementById("li13");
var ul2 = document.getElementById("ul2");
var li23 = document.getElementById("li23");
ul2.appendChild(li12);
ul1.insertBefore(li23,li13);
</script>
2.8 删除节点
removeChild()方法从DOM中删除一个子节点,节点不能主动删除自己,必需由父节点删除它。
父节点.removeChild(子节点);
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
td{padding: 5px 10px;border: 1px solid #000;}
</style>
</head>
<body>
<ul id="ul">
<li>节点1</li>
<li>节点2</li>
<li>节点3</li>
</ul>
</body>
</html>
<script type="text/javascript">
var snode = document.getElementById("ul");
var firstl = snode.getElementsByTagName("li")[0];
snode.removeChild(firstl);
</script>
2.9 克隆节点
cloneNode()方法可以克隆节点,克隆出的节点是孤儿节点,需要上树。
var 孤儿节点 = 老节点.cloneNode();
var 孤儿节点 = 老节点.cloneNode(true);
//参数是一个布尔值,表示是否采用深度克隆。
//如果为true,则该节点的所有后代也都会被克隆
//如果为false,则只克隆该节点本身
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
td{padding: 5px 10px;border: 1px solid #000;}
</style>
</head>
<body>
<div id="box1">
<ul id="ul">
<li>节点1</li>
<li>节点2</li>
<li>节点3</li>
</ul>
</div>
<div id="box2"></div>
<div id="box3"></div>
</body>
</html>
<script type="text/javascript">
var box1 = document.getElementById("box1");
var ul = box1.getElementsByTagName("ul")[0];
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
var ul2 = ul.cloneNode();
box2.appendChild(ul2);
var ul3 = ul.cloneNode(true);
box3.appendChild(ul3);
</script>
3. 延迟运行
在测试DOM代码时,通常js代码一定要写到html节点的后面,否则js无法找到相应的html节点。
可以使用
window.onload=function(){}事件,使页面加载完毕后,再执行指定的代码。
window.onload=function{
alert("hello world");
}