第10天

155 阅读6分钟

Day 10

DOM文档对象模型

之前经常用document.write,也可以看出这是一个文档对象。不过直接在控制台输出document的话,看到的是一个和element一样的HTML格式的内容,要想看到真正document对象的内容,要放到数组[document]来看。

document是最大的文档对象,HTML、head、body都是文档对象的内容

节点Node

构成HTML网页的最基本单元,每一个部分都可以是一个节点,例如HTML标签、属性甚至整个文档都是节点

但这些节点是不同类型的,常见的类型有:

  • 文档节点(文档):整个 HTML 文档。整个 HTML 文档就是一个文档节点。
  • 元素节点(标签):HTML标签。
  • 属性节点(属性):元素的属性。
  • 文本节点(文本):HTML标签中的文本内容(包括标签之间的空格、换行)。

不过一般找节点都是找文档节点和元素节点

DOM树

实际上就是Html结构(包含div之类的)

DOM的作用

  • 找对象(元素节点)
  • 设置/修改元素的属性值
  • 设置/修改元素的样式
  • 动态创建和删除元素
  • 事件的触发响应:事件源、事件、事件的驱动程序

DOM找元素/节点的方法

总的来说,都是通过document对象的方法来获取的,以下是常用的三种方式

一、通过标签名称获取多个元素

//获取h1元素(可以获取多个
var h1s = document.getElementByTagName('h1')
console.log(h1s)

二、通过ID获取元素

//获取特定ID的元素(只能获取一个
var qwer = document.getElementById("qwer")
console.log(qwer)

三、通过class获取元素

//获取h1元素(可以获取多个
var classss = document.getElementByClassName('calssss')
console.log(classss)

四、document.querySelector一个方法找所有元素(最好用也最常用)

可以获取多个并不是什么好事,假如我只想要某标签或者某calss的某一个元素呢?可以像CSS那样单独选择吗,当然可以。

上面三种方法是ES5就能用的,ES6就有了更好的方法:

document.querySelector

<h1>helloworld1</h1>
		<h1>helloworld2</h1>
		<h1 id="abc">helloworld3</h1>
		<h1 class="cba">helloworld4</h1>
		<h1 class="cba">helloworld5</h1>
		<div id="d1">
			<h1 class="cc">helloworld6</h1>
		</div>
		<script type="text/javascript">
			//完全是css选择器的方式,比如选择第4个子元素(详见后面一节)
			var zzz = document.querySelector('.cba:nth-child(4)')
			console.log(zzz);
			console.log("————————————————————————");

			//document.querySelector返回最先匹配到的第一个对象
			var cba = document.querySelector('.cba')	//如果有多个的话只返回第一个
			console.log(cba)
			
			var abc = document.querySelector("#abc")	//和CSS选择器一样的获取id
			console.log(abc)
			
			var abc1 = document.getElementById("abc")
			//通过document.querySelector和document.getElementById获取到的对象是同样的
			console.log(abc===abc1)
			
			var a6 = document.querySelector('#d1>.cc')	//选择id下的class,也和CSS选择器一样
			console.log(a6)
			
			//只能返回第一个的话,要是就像要多个的话怎么办?用querySelectorAll
			//document.querySelectorAll获取所有匹配到的元素对象
			var cbas = document.querySelectorAll('.cba')
			console.log(cbas)
			
			//让所有cbas元素都设置背景色为skyblue
			cbas.forEach(function(item,i,arr){
				item.style.background = "skyblue"
			})
		</script>

DOM找父子关系节点

如何用document来找某元素的父元素或者子元素嗯

注意获取节点和获取元素的区别

<div class="d1">
			helloworld1
			<h3>child1</h3>
			<h3>child2</h3>
			<h3>child3</h3>
		</div>
		<div class="d2">helloworld2</div>
		<div class="d3">helloworld3</div>
		<script type="text/javascript">
			var d1 = document.querySelector('.d1')
			console.log([d1])
			console.log("——————————————分割线————————————");

			//获取父节点parentNode / parentElement(这两个方法都可以)
			var hhh = d1.parentElement	//d1的父节点就是body
			console.log(hhh);
			
			//获取子元素 children(元素)/childNodes(节点)
			var first =  d1.children[0]
			//d1.firstElementChild,获取第一个元素
			var last =  d1.children[d1.children.length-1]
			//d1.lastElementChild,获取最后1个元素
			console.log(first)
			console.log(last)
			console.log("——————————再次的分割线————————");
			//获取d1的子节点
			var zzz = d1.childNodes
			console.log(zzz);	//可以在控制台看节点有哪些(共7个
			
			//获取d1下的h3的第2个子元素
			var child2 = document.querySelector('.d1 h3:nth-child(2)')
			console.log([child2])
			//获取兄弟元素的下一个元素,nextElementSibling
			//获取兄弟元素的上一个元素,previousElementSibling
			//一般都是找元素,如果找节点的话,很容易找到的是text
			//以上都可以通过console控制台点开来看
		</script>

DOM节点的操作

操作都是函数(方法),所以有括号,要传参数

创建/添加和删除节点

在某元素后面添加:添加子元素的父元素.appendChild(创建的元素)

在某元素之前添加:插入元素的父元素.insertBefore(img,d3)

删除某元素:要删除元素的父元素.removeChild(要删除的元素)

<div class="d1">hello1</div>
		<div class="d2">hello2</div>
		
		
		<div class="d3">hello3</div>
		<div class="d4">hello4</div>
		<div class="d5">hello5</div>
		
		<script type="text/javascript">
			//1创建元素
			var h1 =  document.createElement("h1")	//这里的参数是标签名
			console.log([h1])
			console.log(typeof h1)	//查看类型
			//2设置元素的内容
			h1.innerHTML = "中午吃啥?"
			//3插入元素,首页要找到被插入的元素(要把创建的元素放在哪
			var d1 = document.querySelector(".d1");
			//4追加子元素(放在后面
			d1.appendChild(h1)

			
			//可以在什么前面插入元素吗(放在前面
			//创建img元素
			var img = document.createElement('img')	//这里创建img标签
			//设置img的src属性
			img.src = "img/cxk.jpg"
			console.log(img)
			//找到被插入的父元素,<body>
			var body =  document.querySelector('body')	
			//在body的d3前插入内容.insertBefore
			var d3 = document.querySelector('.d3')
			body.insertBefore(img,d3)	//第二个参数表示插入到哪个元素前面
			//d3.parentElement.insertBefore(img,d3)

			
			//如果想在d5的位置再插入一张图的话,用这个方法可行吗
			//不可行,因为设置var d5 = document.querySelector('.d5')的话,内存地址就给到其他对象了,所以就只剩下一张图片了
			//如果重新创建的话,又要再写属性?如果多张图的话岂不是得累死
			//就可以用img.cloneNode()方法了
			var img2 = img.cloneNode()	//不带参数的话,只复制节点本身不复制子节点;带参数true则也复制子节点
			//将图追加到d5
			var d5 = document.querySelector('.d5')
			d5.appendChild(img2)



			//删除元素.removeChild,顾名思义,不仅要找到元素本身还要找到其父元素
			//1找到被删除的父元素
			var body = document.querySelector('body')
			//2找到要删除的元素
			var d2 = document.querySelector('.d2')
			//3删除,父元素.removeChild(子元素)
			body.removeChild(d2)
			//可以发现,以上方法都要找父元素,都要多写一行,比较麻烦
			//d2.parentElement.removeChild(d2),这样可以少写一个找到父元素的步骤1
		</script>

获取和设置/修改以及删除元素的属性

<body>
		<div id="d1">
			helloworld
		</div>
		<img id="img1">
		<script type="text/javascript">
			var d1 = document.querySelector("#d1");
			console.log([d1])
			//获取属性值的三种方法
			console.log(d1.id)
			console.log(d1['id'])
			console.log(d1.getAttribute('id'))
			//设置属性值的三种方法(对应获取方法
			d1.id = "d2"
			d1['id'] = "d3"
			//setAttribute("属性名称","属性值")
			d1.setAttribute("id","d4")	//需要两个参数
			
			//以上一节的内容为例,修改img元素的src属性
			var img = document.querySelector('#img1')
			img.setAttribute("src","img/cxk.jpg")
			
			//这两种方式有什么区别吗
			//d1.abc = "789";//默认元素中如果不存在此属性,那么此属性只会创建在对象中,不会显示在元素的html上
			//例如img的src是默认存在的属性

			///默认元素中如果没有此属性,那么此属性不会创建在对象的属性中,会显示在html的属性中.
			d1.setAttribute("abc","789")	//html结构中是真的有abc的
			console.log(d1)
			console.log([d1])
			

			//删除属性
			d1.removeAttribute("abc")
		</script>
	</body>