慕课前端入门-DOM

1. DOM

DOM是JS操控html和css的桥梁
html不能使用字符串思维,要使用节点思维。
DOM(Document Object Model,文档对象模型)是Javascript操作html文档的接口,使文档操作变得非常优雅,简便。
DOM最大的特点是将文档表示为节点树。

2.node

2.1 nodeType常用属性值

noteType值节点类型
1元素节点
3文字节点
8注释节点
9document节点
10DTD节点

2.2 访问元素节点

  • 所谓访问元素节点,就是指得到、获取页面上的元素节点
  • 对节点进行操作,第一步就是要得到它
  • 访问元素节点,主要依靠document对象
    • document对象是DOM中最重要的东西,几乎所有DOM的功能都封装在了document对象中
    • document对象也代表整个html文昌,它是DOM节点树的根
    • document对象的noteType属性值是9
访问元素节点的常用方法
方法说明示例
document.getElementById()
通过ID得到元素
  1. 如果页面上有多个相同id的元素,则只能得到第1个
  2. 不管元素藏的位置多深,都能通过ID把它找到
document.getElementById("box1");
document.getElementsByTagName()
通过标签名得到元素数组
  1. 数组方便遍历,从而可以批量操控元素节点
  2. 即使页面上只有一个指定标签名的节点,也将得到长度为1的数组
  3. 任何一个节点元素也可以调用getElementsByTagName()方法,
    从而得到其内部的元素节点
document.getElementsByTagName("div");
document.getElementsByClassName()
通过类型得到元素数组
  1. getElementsByClassName方法从IE9开始兼容
  2. 某个节点元素也可以调用getElementsByClassName()方法,从而得到其内部的元素节点
document.getElementByClassName("squar200")
document.querySelector()
通过选择器得到元素
  1. querySelector方法只能得到页面上的一个元素,如果有多个元素符合条件,则只能得到第1个元素
  2. querySelector方法从IE8开始兼容,但从IE9开始支持CSS3的选择器,如nth-child(),:[src^='dog']等CSS3选择器形式都支持良好
document.querySelector('#box p:nth-child(1)');
document.querySelectorAll()
通过选择器得到元素数组
  1. 即使页面上只有1个符合选择器的节点,也将得到长度为1的数组
  2. querySelectorAll只能由document发起,不能有节点发起。
document.querySelectorAll("#list1 li");

2.3 节点的关系

节点关系
关系考虑所有节点只考虑元素节点
子节点childNodeschildren
父节点parentNode相同
第一个子节点firstChildfirstElementChild
最后一个子节点lastChildlastElementChild
前一个子节点previousSiblingpreviousElementSibling
后一个子节点nextSiblingnextElementSibling

注意:文本节点也属于节点。在标准的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");
}
posted on 2020-09-15 11:17  singleSpace  阅读(204)  评论(0编辑  收藏  举报