DOM 这是核心部分
文档对象模型(DOM) 可以将 web 页面 与 脚本或编程语言 连接起来
初识DOM
- web页面
这里的 web 页面,也就是之前我们用 HTML 和 CSS 绘制的页面,也称作为文档
- 脚本或编程语言 为什么这里不直接说将 Web 页面和 Javascript 语言连接起来,而要绕一下说脚本或编程语言呢?
因为 DOM 是一种规范,或者是一种约定,只要遵循这个规范,那么无论是 Javascript ,还是python ,或者 java 都可以被连接起来。
➤DOM映射:像HTML和xml文档都是树状结构,web网页最终会映射为一颗DOM树,DOM树连接js语言
DOM 树特性:(树)
- 树根是 DOCUMENT,也可以称为整个页面文档
- 每个 HTML 标签我们称之为 DOM 节点,英文为Node或者Element
- 每个 HTML 标签包裹的子标签,在树上体现为分支,称为儿子节点。比如上图,
p
和H1
都是 div 的儿子节点。 div 同样也是 Body 的儿子节点。- 儿子节点类推可以得知
P
,H1
是 Body 的孙子节点- 所有
P
,H1
的长辈,我们称为P
和H1
的祖先节点,P
,H1
是亲兄弟,我们称为兄弟节点。
Google插件可以帮助初学者理清网页中的DOM树
访问
DOCUMENT
元素会存在全局变量 window 下面
console.log(window.document);
//或者
document+敲回车
选择器查询 querySelector
document.querySelector(div);//从上往下第一个
document.querySelector('main .core .subtitle');
迭代查询
let subtitle = document.querySelector('main .core .subtitle');
let a = subtitle.querySelector("a");
console.log(a);
选择器全量查询 querySelectorAll()
document.querySelectorAll('input');
在浏览器的console里也可以通过get来查看当前页面的dom内容(用得不多)
document
document.getElementById
document.getElementByName
document.getElementByClassName
document.getElementByTagName
DOM属性
<!-- HTMLDocument 根文档 -->
<html>
……
</html>
<!-- HTMLDivElement DIV类型 -->
<div class="subtitle">
……
</div>
<!-- HTMLAnchorElement 超链接类型 -->
<a class="free-bright">免费靓号</a>
<!-- HTMLInputElement Input类型 -->
<input class="password" type="pasworkd" placeholder="请输入密码" />
每一种HTML标签都有一种DOM类型对应
- 元素节点
- 特性节点
- 文本节点
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>标题</title>
</head>
<body>
<div id="test"></div>
<script src="./index.js"></script>
</body>
let divDom = document.querySelector('#test');
console.log(divDom.nodeType, divDom.nodeName, divDom.nodeValue);
// 获取DIV节点的第一个儿子节点,代表 '标题' 这个字符串
let txtDom = divDom.firstChild;
console.log(txtDom.nodeType, txtDom.nodeName, txtDom.nodeValue);
// 获取DIV节点的id属性
let attDom = divDom.attributes.id;
console.log(attDom.nodeType, attDom.nodeName, attDom.nodeValue);
节点 | nodeType | nodeName | nodeValue | 类型 |
---|---|---|---|---|
divDom | 1 | DIV | null | 元素节点 |
txtDom | 2 | #text | 标题 | 文本节点 |
attDom | 3 | id | test | 特性节点 |
- 整个 HTML 中,无论是标签,标签属性,还是纯文本字符串都是
Element
,不同的地方在于nodeType
分别为1,2,3
- HTML 标签都是元素节点,可以用
nodeName
获取标签名称 - 纯文本都是文本节点,可以用
nodevalue
获取文本内容 - 标签的每个属性都是特性节点,可以用
nodeName
取得属性Key,用nodevalue
取得属性 Value attributes
可以获取元素节点的所有属性,得到的结果是一个字典,通过属性 Key 获取对应的特性节点。
DOM内容
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>oageux</title>
</head>
<body>
<div id="test">
文本内容
<p>第一个p标签</p>
<p>第二个p标签</p>
</div>
<script src="./index.js"></script>
</body>
let divDom = document.querySelector('div#test');
console.log(divDom.outerHTML, divDom.innerHTML, divDom.innerText);
属性 | 值 | 总结 |
---|---|---|
outerHTML | <div id="test">文本内容<p>第一个p标签</p><p>第二个p标签</p></div> | 整个DOM的HTML代码 |
innerHTML | 文本内容<p>第一个p标签</p><p>第二个p标签</p> | DOM内部HTML代码 |
innerText | 文本内容 | DOM内部纯文本内容 |
DOM亲属
属性 | 值 | 总结 |
---|---|---|
firstChild | 文本内容 | 指定节点的第一个子节点 |
lastChild | <p>第二个p标签</p> | 指定节点的最后一个字节点 |
childNodes | 优课达<p>第一个p标签</p><p>第二个p标签</p> | 指定节点的子节点的集合 |
parentNode | <body><div id="test">文本内容<p>第一个p标签</p><p>第二个p标签</p></div><script src="./index.js"></script></body> | 指定节点在DOM树中的父节点 |
DOM样式
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>1234</title>
</head>
<body>
<h1 class="oageux" style="color: #FF3300; font-size: 24px;">文本内容</h1>
<script src="./index.js"></script>
</body>
const h1Dom = document.querySelector('h1');
console.log(h1Dom.classList);
console.log(h1Dom.style);
console.log(h1Dom.style.color);
属性 | 类型 | 值 | 总结 |
---|---|---|---|
classList | DOMTokenList 类数组 | ['test', 'youkeda'] | classList数组方式存储所有的class名称 |
style | CSSStyleDeclaration | color 属性为rgb(255, 51, 0) | 对象或字典的方法存储CSSStyle |
也可以更改样式
let a = document.querySelector("title").style.color = "red";
DOM操作
通过前面的学习已经能用js完成网页的内容提取
接下来我们通过实战来理解这部分
大家想象一个图标,右上角有一个圈儿,点击可以选中,并√,再次点击可以取消√
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="./post.css" />
<title>标题</title>
</head>
<body>
<section class="box">
<img
class="java"
src="对应图片路径"
/>
<div class="title">Java</div>
<div class="select"></div>//圆圈选择框
</section>
<script src="./post.js"></script>
</body>
我们可以在点击的时候,向
select
插入一个img
节点,渲染选中的打钩图片。然后再次点击的时候清除select
内部节点。
- 如何使用 Javascript 创建节点?(在这里创建
img
节点) - 如何设置节点的样式、属性?(
img
节点设置src
属性) - 如何在已存在节点内部添加子节点?(
img
节点需要添加到
select
中) - 如何清空节点内部子节点?(再次点击时清空
select
的子节点)
// 保存当前是否选中的状态
let isSelected = false;
// 获取整个元素的节点
const box = document.querySelector('.box');
// 获取select框节点
const select = document.querySelector('.select');
// 给整个元素添加点击事件【大家可以先忽略这部分】
box.addEventListener('click', function () {
// 点击以后触发这个函数
// 修改当前选中状态,取反即可
isSelected = !isSelected;
// 如果当前是选中状态、则添加img到select中
if (isSelected) {
// 创建一个img标签节点
const img = document.createElement('img');
// 设置img的src属性和样式,让其撑满select框
img.src = '√的图片';
img.setAttribute('style', 'width: 100%; height: 100%;');
// 将这个节点添加到select框中
select.appendChild(img);
} else {
// 如果不是选择状态,则清空内部子元素
select.innerHTML = '';
}
});
- 创建标签节点
const div = document.createElement('div');
const txt = document.createTextNode('文本内容');
- 添加新节点
const div = document.createElement('div');
const txt = document.createTextNode('文本信息');
div.appendChild(txt);
document.body.appendChild(div);
appendChild(newNode):在所有儿子节点之后添加
inserBefore(newNode, referenceNode):在某个目标儿子节点之前添加
举个例子:在sars,添加H1N1,新型冠状病毒
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>标题</title>
</head>
<body>
<ul class="root">
<li class="sars">SARS</li>
</ul>
<script src="./index.js"></script>
</body>
const root = document.querySelector('ul.root');
const sars = document.querySelector('li.sars');
// 创建 H1N1
const H1N1 = document.createElement('li');
const H1N1Txt = document.createTextNode('H1N1');
H1N1.appendChild(H1N1Txt);
root.appendChild(H1N1);
// 创建 新型冠状病毒
const nCoV = document.createElement('li');
const nCoVTxt = document.createTextNode('新型冠状病毒');
nCoV.appendChild(nCoVTxt);
root.insertBefore(nCoV, sars);
最终顺序就是
<ul class="root">
<li>新型冠状病毒</li>
<li>SARS</li>
<li>H1N1</li>
</ul>
思考:问题是重复的代码太多,如果添加100疾病呢?
答:我们可以使用函数来简化
function createDisease(txt) {
const dom = document.createElement('li');
const domTxt = document.createTextNode(txt);
dom.appendChild(domTxt);
return dom;
}
const root = document.querySelector('ul.root');
const sars = document.querySelector('li.sars');
// 创建 H1N1
const H1N1 = createDisease('H1N1');
root.appendChild(H1N1);
// 创建 新型冠状病毒
const nCoV = createDisease('新型冠状病毒');
root.insertBefore(nCoV, sars);
- 设置样式和属性
img.setAttribute('style', 'width: 100%; height: 100%;');
dom.style
是一个Map对象,也可以单独设置属性
dom.style.color = 'xxxx';
classList
可以使用classList获取DOM所有类,进行add,remove,toggle,replace等等
- innerHTML
案例中用innerHTML = ''
清空select
节点所有的后代内容。
当然也可以给某个元素添加内容
function createDisease(txt) {
const dom = document.createElement('li');
// 我们可以直接用innerHTML设置其纯文本
dom.innerHTML = txt;
return dom;
}
OK,对DOM的认识,访问,属性和简单的操作就是以上部分,下一期我将发布剩下的比较难以理解的DOM操作,会以项目形式学习,敬请期待!