一、初识 DOM<br />文档对象模型,Document Object Model <br />1.1 web 页面<br />这里的web 页面,也就是之前我们用HTML 和 CSS 绘制的页面,也称为文档
1.2 脚本或编程语言
因为 DOM 是一种规范,或者是一种约定,只要遵循这个规范,无论是Javascript,还是python,或者java 都可以被连接起来。
1.3 DOM 映射
我们总结一下DOM 树特性
1、树根是DOCUMENT,也可以称为整个页面文档
2、每个 HTML 标签我们称之为DOM 节点,英文为Node 或者 Element
3、每个HTML 标签包裹的自标签,在树上体现为分支,称为儿子节点。
4、儿子节点类推可以得知p, H1 是 BODY 的孙子节点
5、所以p 、H1 的长辈,我们称为 P 和 H1 的祖先节点
6、P、H1 是亲兄弟,我们称为兄弟节点。
二、访问DOM
2.1 获取 DOCUMENT
web 网页最终会映射为一棵DOM 树,DOM 树连接网页和Javascript 语言。
我们如何获取DOM 数的根部元素呢?
DOCUMENT 元素会存在全局变量window 下面,我们可以通过如下代码来访问:
window.document
window.document 得到的是一个HTMLDocument 对象,这个对象内容有点多,大家不需要全部了解,只需要看几个属性即可,比如document 内容 key 为 documentElement;
2.2 选择器查询
选择器查询方法 —- querySelector()
完整的代码为:document.querySelector(‘main .core .subtitle’);
2.3 迭代查询
当我们得到subtitle 元素后,我们还可以利用这个元素,继续筛选器内部元素,比如我们想筛选器内部的a 标签,我们可以继续完善代码:
let subtitle = document.querySelector(‘main .core .subtitle’);
console.log(subtitle.querySelector(‘a’));
2.4 选择器全量查询
querySelectorAll()
document.querySelectorAll(‘input’);
2.5 其他筛选方法
querySelector 和 querySelectorAll 是最新提出的方法
getElementById():根据id 查询某个节点
getElementsByClassName():根据class 查询多个节点
getElementsByTagName():根据标签名查询多个节点
两者的区别:querySelector 查询出来的元素是拷贝的原始数据,不会再随着页面 DOM 节点的改变而变化get 系列方法查询出来的元素就是原始数据,所以会随着页面的DOM 节点的改变而变化。
大部分都是用querySelector(All)
三、DOM 属性
3.1 DOM 种类
https://developer.mozilla.org/zh-CN/docs/Web/API
在页面中搜索 Element
3.2 DOM 属性
DOM 类型
在上面我们看到很多DOM 种类,但可以归纳为几个类别:
1、元素节点
2、特性节点
3、文本节点
4、…… 其他类别不重要,忽略
let divDom = document.querySelector(‘div#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);
3.3 DOM 内容
let divDom = document.querySelector(‘div#test’);
console.log(divDom.outerHTML, divDom.innerHTML, divDom.innerText);
3.4 DOM 亲属
在上面我们知道可以利用firstChild 属性获取到元素的第一个儿子节点。那么还能获取哪些其他亲属呢?
let divDom = document.querySelector(‘div#test’);
console.log(divDom.firstChild, divDom.lastChild);
console.log(‘—————-‘);
console.log(divDom.childNodes);
console.log(‘—————-‘);
console.log(divDom.parentNode);
3.5 DOM 样式
通过DOM,我们同样可以访问到其CSS 特性
<!DOCTYPE html>
优课达
3.6 DOM 数据属性
网页设计的初衷是数据和特定的HTML 标签相关联。
HTML 提供一种数据属性的标准,利用data- 允许我们在标准内于HTML 元素中存储额外的信息。
<!DOCTYPE html>
…
对文章而言,除了文章内容,我们还有其他额外数据,例如:段落、字数、分类,etc… 那这些额外数据我们就可以利用data- 来存储。
那我们该怎么通过JS 来获取呢? 按上面的推理,肯定也存在 DOM 的某个属性中
const article = documment.querySelector(‘article’);
console.log(article.dataset);
从结果可以看出,dataset 是个 Map 对象,它是data- 这个 的 Key-Value 集合。
3.7 总结
记住大概意思
四、DOM 操作(一)
4.1 DOM 样式修改
思考以下问题:
1、如何使用 Javascript 创建节点?(在这里创建 img 节点)
2、如何设置节点的样式、属性?(img 节点设置 src 属性)
3、如何在已存在节点内部添加子节点?(img 节点需要添加到 select 中)
4、如何清空节点内部子节点?(再次点击时清空 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 = ‘https://style.youkeda.com/img/sandwich/check.png‘; img.setAttribute(‘style’, ‘width: 100%; height: 100%;’); // 将这个节点添加到select框中 select.appendChild(img);
} else {
// 如果不是选择状态,则清空内部子元素
select.innerHTML = ‘’;
}
});
1、创建标签节点
document.createElement(tagName)
此方法用于创建一个由标签名称tagName 指定的 HTML 元素,也就是上节课提到的元素(标签)节点。
如果想创建一个div 标签,我们可以使用:
const div = document.createElement(‘div’);
document.createTextNode(string)
如果想继续在这个div 标签内部,添加纯文本,可以继续使用创建文本方法document.createTextNode(),代码如下:
const div = document.createElement(‘div’);
const txt = document.createTextNode(‘优课达-学的比别人好一点’);
我们继续把txt 添加到div 中,把div 添加到body 中,代码如下:
const div = document.createElement(‘div’);
const txt = document.createTextNode(‘优课达-学的比别人好一点’);
div.appendChild(txt);
document.body.appendChild(div);
2、添加新节点
appendChild(newNode)
在上面的案例中,我们多次用到appendChild(),此方法可以往该节点中插入儿子节点。
insertBefore(newNode, referenceNode)
此方法和 appendChild() 刚好相反,appendChild 是在所有儿子节点之后添加,insertBefore 是在某个目标儿子节点之前添加。
insertBefore(newNode , referenceNode),需要两个参数,newNode 表示新节点, referenceNode 表示目标节点,也就是新节点插入到目标节点之前。
我们来看一个例子:
那如果我们想添加100 个疾病节点,那么该怎么办呢?
我们来修改这下这个代码
3、设置样式、属性
在上面,我们通过如下代码设置CSS 样式,这个和直接在HTML 代码中写style 语法一样。
img.setAttribute(‘style’ , ‘width: 100% ; height: 100%’);
上节课我们知道dom.style 是一个Map 对象,因此如果我们不想全量替换样式,我们还可以单独设置某些属性,如下代码:
dom.style.color = ‘xxxx’;
setAttribute()不仅仅可以设置style 之外,所有HTML 属性都能用他设置,比如 id, src, type, disabled, etc…….
classList 参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/classList
4、innerHTML
在案例中,我们使用 innerHTML = ‘ ‘ 清空 select 节点所有的后代内容。
五、DOM 操作(二)
5.1 我们先来看个例子
简单的百度搜索
分解下页面开发步骤:
1、首先,我们在不考虑鼠标交互的情况下,完成静态HTML 页面
2、监听搜索框 Input 输入事件(这部分代码内置)
3、当输入内容是肺炎时,显示模糊搜索结果
4、当输入内容不是肺炎时,显示登录查看历史
开发静态 HTML 页面
监听Input 输入事件,处理区域显示隐藏
监听输入肺炎时,显示肺炎查询结果
首先我们修改CSS 将登录查看历史设置可见,将搜索结果设置不可见
main .search-result {
padding : 0;
display: none;
}
接着修改Javascript 代码,动态控制显示和隐藏如下:
肺炎搜索结果动态显示
这部分数据是由 Javascript 发起网络请求返回数据,然后利用动态生成节点的方法插入页面。
我们封装一个函数,用于生成这个 li DOM 节点,代码如下:
function createSearchItem(txt) {
const item = document.createElement(‘li’);
item.innerHTML = <i class="search"></i><p>${txt}</p><i class="edit"></i>
; return item;
}
在这里我们使用 innerHTML 和 模板字符串 快速创建 li 内容。
最后我们需要遍历搜索结果数据数组,依次创建 li ,并插入到页面中,代码如下:
let data = [
‘肺炎实时疫情动态’,
‘肺炎的症状有哪些症状’,
‘肺炎武汉’,
‘肺炎症状’,
‘肺炎最新’,
‘肺炎是怎么引起的’,
‘肺炎最新消息’,
‘肺炎实时’,
‘肺炎症状及表现’,
‘肺炎最新情况’
];
function createSearchItem(txt) {
const item = document.createElement(‘li’);
item.innerHTML = <i class="search"></i><p>${txt}</p><i class="edit"></i>
; return item;
}
const input = document.querySelector(‘input’);
const login = document.querySelector(‘.login’);
const searchResult = document.querySelector(‘.search-result’); // 监听键盘事件 input.addEventListener(‘keyup’, function() {
// this 是DOM节点,this.value可以获取input内输入的值
if (this.value === ‘肺炎’) {
// 先把原始内容清空
searchResult.innerHTML = ‘’;
for (let i = 0; i < data.length; i++) { searchResult.appendChild(createSearchItem(data[i]));
}
login.style.display = ‘none’;
searchResult.style.display = ‘block’;
} else {
login.style.display = ‘block’;
searchResult.style.display = ‘none’;
}
});
总结
我们总结下本节课的解决思路:
首先我们在不考虑动态效果情况下,把页面中涉及到的所有元素都用静态页面的形式写出来
其次利用Javascript 控制区域的显示和隐藏,达到动态效果。
最后根据写好的静态页面模板和数据,动态创建哎DOM 节点。