JavaScript学习——进阶(续5:DOM)

DOM

定义

DOM(Document Object Model)定义了表示和修改文档所需的方法。DOM对象为宿主对象,由浏览器厂商定义,用来操作HTML和XML。也有人称DOM是HTML以及XML的标准编程接口。

几个实例

  • 点击指定div区域,使其背景颜色改变
<body>
	<div> </div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
		div.style.width = '100px';
		div.style.height = '100px';
		div.style.background = 'lightblue';
		//第一次点击时变粉色,第二次点击时变蓝色:
		var count = 0;
		div.onclick  = function() {
			count++;
			if (count % 2 == 1) {
				div.style.background = 'pink';
			} else {
				div.style.background = 'lightblue';
			}
		}
	</script>
</body>

在这里插入图片描述

  • 一个选项卡功能
<body>
	<div class="wrapper">
		<button class="active"></button>
		<button></button>
		<button></button>
		<div class="content" style="display:block">星星</div>
		<div class="content">月亮</div>
		<div class="content">太阳</div>
	</div>
<script type="text/javascript">
	//一个选项卡功能
	var btn = document.getElementsByTagName('button');
	var div = document.getElementsByClassName('content');
	for (var i = 0; i < btn.length; i++) {
		(function (n) {
			btn[n].onclick = function () {
				for (var j = 0; j < btn.length; j++) {
					btn[j].className = "";
					div[j].style.display = "none";
				}
				this.className = "active";
				div[n].style.display = "block";
			}
		}(i))
	}
</script>
</body>

在这里插入图片描述

  • 在页面上写一个动态的div区域
<body>
	<script type = "text/javascript">	
		var div = document.createElement('div');
		document.body.appendChild(div); //添加div
		div.style.width = "100px"; 		//设置div样式
		div.style.height = "100px";
		div.style.backgroundColor = "pink";
		div.style.position = "absolute";
		div.style.left = "0";
		div.style.top = "0";

		//版本1:匀速横向运动
/*		setInterval(function () { //定时器:每隔100ms执行一次这里的函数
			div.style.left = parseInt(div.style.left) + 1 + "px"; //横向位置的变换
		}, 100)
		
		//版本2:加速运动
		var speed = 1;
		setInterval(function () { //定时器:每隔100ms执行一次这里的函数
			speed += speed/7;     //加速运动
			div.style.left = parseInt(div.style.left) + speed + "px"; //横向位置的变换
			div.style.top = parseInt(div.style.top) + speed + "px";	  //纵向位置的变换
		}, 100) 

		//版本3:加速运动,且在指定位置停下
		var speed = 1;
		var timer = setInterval(function () { //定时器:每隔100ms执行一次这里的函数
			speed += speed/7;     //加速运动
			div.style.left = parseInt(div.style.left) + speed + "px";
			div.style.top = parseInt(div.style.top) + speed + "px";
			if(parseInt(div.style.top) > 200 && parseInt(div.style.left) > 200) {
				clearInterval(timer);
			}
		}, 100)
*/

		//版本4:使用键盘的“上下左右”键来操作div的移动
		document.onkeydown = function(e) {
			switch(e.which) {
				case 37: //使div向左移动
					div.style.left = parseInt(div.style.left) - 2 + "px";
					break;
				case 38: //使div向上移动
					div.style.top = parseInt(div.style.top) - 2 + "px";
					break;
				case 39: //使div向右移动
					div.style.left = parseInt(div.style.left) + 2 + "px";
					break;
				case 40: //使div向下移动
					div.style.top = parseInt(div.style.top) + 2 + "px";
					break;				
			}
		}

	</script>
</body>

选择指定标签的几种方法

document 代表整个文档/页面

1 直接选择

document.getElementsByTagName()
document.getElementById() //不常用。在真正开发时,能使用class就不适用id
document.getElementsByClassName() //不常用。因为具有局限性:IE8及以下的IE版本中不可使用
document.getElementsByName() //不常用。只有部分标签才有name属性, 如表单、img、iframe

<body>
	<div>
		<p class="demo"></p>
	</div>
	<p></p>
	<script type = "text/javascript">
		var p = document.getElementsByClassName('demo')[0];
		//无论通过什么来选出一个标签,其返回结果都是一个类数组;
		//如果类数组中只有一个元素,也必须通过“[0]”才能真正的选出这个标签,否则p表示的是一个类数组。
	</script>
</body>

2 通过CSS选择器选出指定标签

document.querySelector() //(只选出一个指定标签)不常用。在IE7及以下的版本中没有
document.querySelectorAll() //(选出所有的符合条件的指定标签)不常用。在IE7及以下的版本中没有 //这两个方法并不常用,其致命缺点是:不具有实时性——通过这两个方法选出来的标签是“死的”,如果后面的代码更改了这些标签,那么通过这两个方法选出来的那些标签仍是不改变的。但如果使用上面的一组方法来选出指定标签,就是“实时性”的,可以随着之后的代码对标签的修改而更新。

<body>
	<div>
		<strong></strong>
	</div>
	<div>
		<span>
			<strong></strong>
		</span>
	</div>
	<script type = "text/javascript">
		var strong = document.querySelector('div > span strong.demo');
		var strong = document.querySelectorAll('div > span strong.demo');
	</script>
</body>

在这里插入图片描述

<body>
	<div></div>
	<div class="demo"></div>
	<div></div>
	<script type = "text/javascript">
		var div1 = document.querySelectorAll('div');
		var div2 = document.getElementsByTagName('div');
		var demo = document.getElementsByClassName('demo')[0];
		var newDiv = document.createElement('div');
		document.body.appendChild(newDiv);
	</script>
</body>

在这里插入图片描述

3 遍历节点树选出指定标签

parentNode //父节点(最顶端为document)
childNodes //所有孩子节点
firstChild //第一个子节点
lastChild //最后一个子节点
nextSibling //后一个兄弟节点
previousSibling //前一个兄弟节点
查看父节点、兄弟节点

<body>
	<div id="only" class="demo">
		<strong></strong>
		<span></span>
		<em></em>
	</div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
		var strong = document.getElementsByTagName('strong')[0];
	</script>
</body>

在这里插入图片描述
在这里插入图片描述
查看所有孩子节点

节点类型

  • 元素节点Element —— 1
  • 属性节点 —— 2
  • 文本节点Text —— 3
  • 注释节点Comment —— 8
  • document —— 9
  • DocumentFragment(文档碎片) —— 11

节点的一个方法

  • hasChildNodes()
    在这里插入图片描述

节点的四个属性

  • nodeName: 返回节点名称
  • nodeValue: 只有文本节点和注释节点有该属性,用来查看文本或注释的内容,可以对其进行修改
  • nodeType: 查看节点的类型,返回结果为上面对应的数字
  • attributes: 用来保存一个元素节点的所有属性,是一个类数组
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

【实现一个方法,用来得到某标签的所有孩子节点中的元素节点(不使用children属性):】

<body>
	<div>
		123
		<strong></strong>
		<span></span>
		<em></em>
	</div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];

		function retElementChild(node) {
			var temp = { //定义一个类数组,用来保存返回的结果
				length : 0,
				push : Array.prototype.push,
				splice : Array.prototype.splice
			};
			var child = node.childNodes;
			var len = child.length;
			for(var i = 0; i < len; i++) {
				if(child[i].nodeType === 1) {
					temp.push(child[i]);
				}
			}
			return temp;
		}

		console.log(retElementChild(div));
	</script>
</body>
<body>
	<div>
		123
		<strong></strong>
		<span></span>
	</div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
	</script>
</body>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4 遍历元素节点树选出指定标签

parentElement //IE9以下不兼容
children
firstElementChild //IE9以下不兼容
lastElementChild //IE9以下不兼容
nextElementSibling //IE9以下不兼容
previousElementSibling //IE9以下不兼容

<body>
	<div>
		<strong></strong>
		<span></span>
		<em></em>
	</div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
		var strong = document.getElementsByTagName('strong')[0];
	</script>
</body>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

DOM继承树

DOM结构树代表了一系列继承关系,所以也叫做DOM继承树。
在这里插入图片描述

1. document代表整个文档:
在这里插入图片描述

  • document的构造函数是HTMLDocument

2. Document可以理解成一个构造函数,其特殊之处在于不能new对象,因为这是系统留给自己使用的:
在这里插入图片描述
在这里插入图片描述

  • Document的用处:Document由于是一个构造函数,所以存在原型Document.prototype。这里我们需要知道的是,Document.prototype实际上是作为document的原型。下面可以进行验证——在Document.prototype上添加属性str,则能够在document上进行访问:
    在这里插入图片描述

3. HTMLDocument的原型是Document.prototype,即:

HTMLDocument.prototype = {

	__proto__: Document.prototype
}
  • document和Document之间的关系就是:document继承自HTMLDocument.prototype,而HTMLDocument.prototype又继承自Document.prototype。

继承关系展示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. Text:文本节点的方法直接继承自Text的原型;
Comment:注释节点的方法直接继承自Comment的原型。
5. head, body等标签直接继承自HTMLHeadElement.prototype, HTMLBodyElement.prototype等。

<script type = "text/javascript">
	HTMLElement.prototype.test = 'test';
	HTMLBodyElement.prototype.str = 'abc';
	var body = document.getElementsByTagName('body')[0];//得到body标签中的所有属性
	var head = document.getElementsByTagName('head')[0];//得到head标签中的所有属性
</script>

看下面的输出结果,可以清楚的知道其中的继承关系:
在这里插入图片描述

由于继承关系的限定,有:

  1. getElementById方法定义在Document.prototype上,故Element节点不能调用该方法。
  2. getElementByName方法定义在HTMLDocument.prototype上,则非HTMLDocument元素(如XMLDocument、Element)不能调用该方法。
  3. getElementsByTagName方法定义在Document.prototype和Element.prototype上(也因此,getElementsByTagName方法最为常用)。

实例:如何快速锁定到div中的span标签?

<body>
	<div>
		<span></span>
	</div>
	<span></span>
	<script type = "text/javascript">
		//方法1: 不推荐
		var span1 = document.getElementsByTagName('span')[0];
		//方法2: 推荐 【理论支撑:getElementsByTagName方法定义在了Element.prototype上】
		var div = document.getElementsByTagName('div')[0]; //在文档范围内寻找第一个div标签
		var span = div.getElementsByTagName('span')[0]; //在第一个div标签范围内寻找第一个span
	</script>
</body>
  1. HTMLDocument.prototype定义了一些常用的属性,如body, head等,它们分别指代< body >,< head >标签。
    在这里插入图片描述
  2. Document.prototype上定义了documentElement属性,指代文档的根元素< html >。
    在这里插入图片描述
  3. getElementsByClassName、querySelector、querySelectorAll在Document.prototype和 Element.prototype上均有定义。

节点的增删改操作

1. 增

document.createElement() //增加元素节点
document.createTextNode() //增加文本节点
document.createComment() //增加注释节点
document.createDocumentFragment() //创建文档碎片节点

注意:使用上面的方法后,只是新增了节点,但还没有把这些节点真正的插入到页面上。还需要使用下面的方法:PARENTNODE.appendChild(a) / PARENTNODE.insertBefore(a, b)(该方法的PARENTNODE必须是div元素,表示:在div中的b前插入a——insert a before b)

  • 实例:
<body>
	<div></div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
		var text = document.createTextNode('Hello World!');
		div.appendChild(text); //如果是想插入到页面上,即<body>标签上,则:document.body.appendChild()

		var span = document.createElement('span');		
		div.appendChild(span);

		var text1 = document.createTextNode('Hi ❤ ');
		span.appendChild(text1);

		span.appendChild(text);//该语句使得div.appendChild(text);失效。这说明appendChild()是"剪切"操作,而不是"复制"操作。
	</script>
</body>

在这里插入图片描述

  • appendChild()的"剪切"效果:
    在这里插入图片描述
    在这里插入图片描述
  • insertBefore():
    在这里插入图片描述
    在这里插入图片描述

2. 删

PARENTNODE.removeChild() //被删除的元素作为该方法的返回值,如需要,可进行保存
CHILDNODE.remove() //被删除的元素被彻底删除,不返回出来。es5中新增
在这里插入图片描述

3. 改

PARENTNODE.replaceChild(new, origin); //new元素替换origin元素

<body>
	<div>
		<span></span>		
	</div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
		var span = document.getElementsByTagName('span')[0];
		var p = document.createElement('p');
	</script>
</body>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

元素节点的属性和方法

1. 元素节点的属性

innerHTML
innerText //火狐中也可使用textContent

<body>
	<div>
		<span></span>		
	</div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
		var span = document.getElementsByTagName('span')[0];
		var p = document.createElement('p');
	</script>
</body>
1.1 innerHTML
  • 查看或修改HTML结构。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
1.2 innerText
  • 查看或修改元素的文本内容。
    在这里插入图片描述
  • 注意,一旦对其进行修改,其内的所有结构也全部消失:
    在这里插入图片描述
    在这里插入图片描述

2. 元素节点的方法

ele.setAttribute(属性名, 属性值) //为ele元素设置属性
ele.getAttribute(属性名)

  • 实例:
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style type="text/css">
		#only{
			font-size:20px;
			color:#fff;
			background-color:pink;
		}
	</style>
</head>
<body>
	<div>
		<span>Hello!</span>
	</div>
	<script type = "text/javascript">
		var div = document.getElementsByTagName('div')[0];
		var span = document.getElementsByTagName('span')[0];
	</script>
</body>

在这里插入图片描述

  • 应用:为所有元素都设置‘this-name’属性,属性值为对应的标签名。
<body>
	<div></div>
	<span></span>
	<strong></strong>
	<script type = "text/javascript">
		var all = document.getElementsByTagName('*');
		for(var i = 0; i < all.length; i++) {
			all[i].setAttribute('this-name', all[i].nodeName);
		}
	</script>
</body>

在这里插入图片描述

  • 应用:使用上面的知识点写出下面的页面结构:
<div c="example"> 
	<p class="slogan" >Hello World!</p>
</div>
<body>
	<script type = "text/javascript">
		var div = document.createElement('div');
		var p = document.createElement('p');
		div.setAttribute('c', 'example');
		p.setAttribute('class', 'slogan');
		p.innerText = 'Hello World!';
		document.body.appendChild(div);
		document.body.appendChild(p);
	</script>
</body>
发布了53 篇原创文章 · 获赞 33 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jy_z11121/article/details/100018643