课程来源:B站后盾人
有关DOM的介绍
在此引用一位大佬的博客的部分内容:
JS-DOM
https://blog.csdn.net/weixin_45077672/article/details/116693698?spm=1001.2014.3001.5501
1.什么是DOM
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言(HTML或者XML)的标准编程接口。
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式。
2.DOM树
文档:一个页面就是一个文档,DOM中使用document表示
元素:页面中所有标签都是元素,DOM中使用element表示
节点:网页中所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM把以上内容都看做是对象
困扰新手的DOM加载问题
3.html
如果不加defer="defer"
,会找不到元素
<!DOCTYPE html>
<html lang="en">
<head>
<!-- defer:内容渲染之后再来执行脚本内容 -->
<script src="3.js" defer="defer"></script>
</head>
<body>
<h2 id="hd">houdunren.com</h2>
</body>
</html>
3.js
const el = document.getElementById('hd')
console.log(el)
运行结果:
如果不加呢?
因为在页面渲染之前就加载了js,这个时候是找不到这个元素的.
将js语句放在body内的最下面试一试:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- defer:内容渲染之后再来执行脚本内容 -->
</head>
<body>
<h2 id="hd">houdunren.com</h2>
<script src="3.js" defer="defer"></script>
</body>
</html>
运行结果:
可见这个方法是可行的.
节点node的概念
- 所有东西都是节点,标签,属性,文本,均是节点(Node)
- document.是节点的起始,节点是一个树状的关系
- document.childNodes是所有的子节点
4.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
</head>
<body>
<h2>houdunren.com</h2>
<!-- 注释也是节点哦 -->
<script> // console.log(document.childNodes[1].childNodes) const h1 = document.childNodes[1].childNodes[2] // 节点类型是用数字进行表示的 console.log('document.nodeType:', document.nodeType) console.log('h1.childNodes[0].nodeType:', h1.childNodes[0].nodeType) console.log('h1.childNodes[0]:', h1.childNodes[0]) console.log('h1.childNodes[1].nodeType:', h1.childNodes[1].nodeType) console.log('h1.childNodes[1]:', h1.childNodes[1]) //h1.childNodes包含些什么?定义的h1到底是啥?打印出来看一下,似乎是整个body 的内容~ console.log('h1.childNodes:', h1.childNodes) </script>
</body>
</html>
运行结果:
容易忘记的是文本,注释也是节点
Node 节点对象的原型继承
重点看代码和console的输出
5.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>后盾人</title>
</head>
<body>
<h2 id="h2 id here">houdunren.com</h2>
<input type="text" id="inputId" value="后盾人" />
</body>
</html>
我把script标签部分单独提出来,这样看起来直观一些.
可以分别关注body内有什么,再看看脚本里写了什么.
body内:一个h2标签,一个input标签.
<script> // h2 是一个对象 const h2 = document.querySelector('h2') // 找它的原型对象:两种方法 console.log('Object.getPrototypeOf(h2):', Object.getPrototypeOf(h2)) console.log('h2.__proto__:', h2.__proto__) function prototype(el) {
const prototypes = [] prototypes.push(el.__proto__) // 为空就不用找了,"..."是解构赋值,展开结果. prototypes.push(...(el.__proto__ ? prototype(el.__proto__) : [])) return prototypes } console.log('prototype(h2):', prototype(h2)) console.log('h2.id:', h2.id) const input = document.querySelector('input') console.log('prototype(input):', prototype(input)) </script>
const h2 = document.querySelector('h2')
是获取h2标签- 下面有找它的原型的方法,但是都比较老旧,并不这么用
.push()
:往这个数组末尾添加一个新的项...
:解构赋值:就是把它里面的东西展开- 如果
el.__proto__
为空还要找,就会报错.
运行结果:
把h2改成h1:看看报错
通过prototype原型操作节点元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>通过prototype原型操作节点元素</title>
</head>
<body>
<h2 onclick="this.color('red')">houdunren.com</h2>
<h1 onclick="this.hide()">向军</h1>
<div onclick="this.color('blue')">this is div element</div>
<script> const h2 = document.querySelector('h2') const h1 = document.querySelector('h1') Node.prototype = Object.assign(Node.prototype, {
color(color) {
// this代表当前触发这个事件的对象 this.style.color = color }, hide() {
this.style.display = 'none' }, }) console.log('h2.__proto__:', h2.__proto__) console.log('h1.__proto__:', h1.__proto__) // 东西没了,也不会报错 </script>
</body>
</html>
- 观察:body里一共有3个元素一个h2,一个h1,和一个div
- this代表当前触发这个事件的对象
运行结果:(点击前)
点击后