JavaScript 学习笔记 ——document
1. 浏览器环境JavaScript 语言最初是为 Web 浏览器创建的。此后,它已经发展成为一种具有多种用途和平台的语言。下面是 JavaScript 在浏览器中运行时的鸟瞰示意图:windows 是根对象,它充当 JavaScript 的全局对象以及代表着浏览器窗口,提供控制浏览器窗口的方法。1.1 DOM 文档对象模型DOM 将所有页面内容表示为可以修改的对象,document 是页面的入口
1. 浏览器环境
JavaScript 语言最初是为 Web 浏览器创建的。此后,它已经发展成为一种具有多种用途和平台的语言。
下面是 JavaScript 在浏览器中运行时的鸟瞰示意图:
windows
是根对象,它充当 JavaScript 的全局对象以及代表着浏览器窗口,提供控制浏览器窗口的方法。
1.1 DOM 文档对象模型
DOM 将所有页面内容表示为可以修改的对象,document
是页面的入口,可以利用它修改创建 HTML 的内容,可以参考 DOM:
document.bodyDOM.style.background = "pink";
let timer = setTimeout(() => {
document.body.style.background = "orange";
}, 5000);
1.2 BOM 浏览器对象模型
BOM
表示由浏览器提供的用于处理 document
之外的所有内容的其他对象,如 navigator
和 location
。利用 location
可以读取当前 URL 和 重定向到新的 URL:
console.log(location.href);
if (confirm("go to baidu.com")) {
location.href = "https://git-jhy.github.io";
}
此外,常用的 alert
、confirm
和 prompt
都是 BOM 的一部分。
2. DOM 树
2.1 DOM 树
看一个简单的 DOM 例子:
<!DOCTYPE HTML>
<html>
<head>
<title>document</title>
</head>
<body>
This is text.
</body>
</html>
-
html
是根节点,head
和body
是它的字节点; -
元素内的文本形成 文本节点,被标记为
#text
,如 title 中的 “document”,包括换行、缩进和空格。 -
若浏览器遇到不正确的 HTML,会在形成 DOM 时自动更正。
上面的 HTML 的 DOM 标签树形结构如下,可以在这个网站上查看 DOM 树结构 Clck me:
一共有 12 种节点类型。实际上,我们通常用到的是其中的 4 种:
- doxument —— DOM 入口
- 元素节点 —— HTML 标签
- 文本标签 —— 包含文本
- 注释 —— 读取注释信息
2.2 遍历 DOM
顶层
html = document.documentElement
body = document.body
head = document.head
注意:若脚本放在 <head>
,则脚本访问不到 docment.body
元素,因为浏览器还未读到它。
子节点
使用 childNodes
、firstChild
和 lastChild
访问子节点,如访问 body
中的所有子元素:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<li>a</li>
<li>b</li>
</body>
<script>
for (let i = 0; i < document.body.childNodes.length; i++) {
console.log(document.body.childNodes[i]);
}
</script>
</html>
结果为:text、li、text、p、text、script、text、script
注意:显示的节点只包含 script 之前的所有 body 子节点。
DOM 集合
DOM 集合是可迭代对象,可以使用 for...of
迭代它,若要使用数组方法,则需要通过Array.from
将集合转化为数组:
console.log(Array.from(document.body.childNodes).filter);
注意
- DOM 集合是只读的
- 不要用 for…in 遍历集合
兄弟节点和父节点
// <body> 的父节点是 <html>
alert(document.body.parentNode === document.documentElenent); // true
// <head> 的下一个兄弟节点
alert(document.head.nextSibing); // body
// <body> 的前一个兄弟节点
alert(document.body.previousSibling); // HTMLHeadElement
2.3 纯元素导航
一般不希望得到文本节点和注释节点,只读取元素节点:
children // 子元素
firstElementChild // 第一个子元素
previousElementSibling // 前一个兄弟元素
parentElement // 父元素
document.documentElement
的父节点为 document
,但父元素节点为 null
。
若要从任意节点到达 <html>
元素节点:
let elem = document.getElementById("a");
while (elem = elem.parentElement) {
console.log(elem);
}
遍历元素:
for (let elem of document.body.children) {
console.log(elem);
}
应用例子
<html>
<body>
<div>Users:</div>
<ul>
<li>John</li>
<li>Pete</li>
</ul>
</body>
</html>
- 从上面的 HTML 中获取 div;
- 获取第二个 li 元素
document.body.firstElementChild;
document.body.children[1].lastElementChild
3. 搜索元素
getElementById
通过 document.getElementById('id')
方法可以获取具有 id
属性的元素,如:
<div id="elem">
<p id="text">text</p>
</div>
<script>
let elem = document.getElementById('text');
elem.style.color = 'orange';
</script>
补充:实际上直接使用 id 作为变量名也可以实现,但不建议!
querySelectorAll
最常用的方法是:elem.querySelectorALL(css)
,css 是一个 css
选择器:
<body>
<div>
<ol>
<li>a</li>
<li>b</li>
</ol>
<p>b</p>
</div>
</body>
<script>
let element = document.querySelectorAll('ol > li:last-child');
element[0].style.color = 'red';
</script>
querySelector
elem.querySelector(css)
也很常用,返回第一个与给定的 CSS 选择器匹配的元素。它等价于 elem.querySelectorAll(css)[0]
matches
使用 elem.matches(css)
可以检查 elem
是否与给定的 CSS 匹配,返回 true
或 false
。
在遍历是可以利用 matches
来进一步筛选元素:
<body>
<ol>
<li id="a.cn">a</li>
<li id="b.com">b</li>
<li id="c.org">c</li>
<li id="d.com">d</li>
</ol>
</body>
<script>
let element = document.querySelectorAll('ol > li');
for (let elem of element) {
// 匹配 id 属性以 com 结尾的 li 标签
if (elem.matches('li[id$="com"]')) {
console.log(elem);
}
}
</script>
getElementsBy*
有以下三种方法:
getElementsByTagName(tag)
:查找具有给定标签的元素;getElementsByClassName(className)
:返回具有给定 CSS类 的元素;getElementsByName(name)
:返回具有name
属性的元素,不常用。
注意:
- 不能漏了
s
- 返回值为一个 集合
3.1 实时性
看一个小例子:
<div>first</div>
<script>
let divs = document.getElementsByTagName('div');
console.log(divs.length); // 1
</script>
<div>second</div>
<script>
console.log(divs.length); // 2
</script>
从上面的例子可以看到:getElementsByTagName
是动态实时的;querySelector
、querySelectorAll
和 getElementById
是静态的。
应用例子
// 筛选 name="search" 的表单
document.querySelectorAll('form[name="search"]');
// 筛选 id 以 com 结尾的 a 标签
document.querySelectorAll('a[id$="com"]');
4. 节点属性
4.1 DOM 节点类
Node
—— 抽象类,充当 DOM 基础,提供树的核心功能:parentNode、nextSibling,childNodes 等;Element
—— DOM 元素的基本类,提供元素级的导航,如 children;HTMLElement
—— 最终是 HTML 元素的基本类,包括 HTMLInputElement,htmlBodyElement 和 HTMLAnchorElement 等;
alert(document.body.constructor.name); // HTMLBodyElement
nodeName、tagName 和 nodeType
- nodeName:节点名,有 undefined, #comment 和 标签名
- nodeType:元素节点为 1, 文本节点为 3, document对象为 9
- tagName:标签名
console.dir(document.body.nodeType); // 1
console.log(document.body.tagName); // BODY
4.2 innerHTML
innerHTML
属性可以将元素内的 HTML 获取为字符串的形式(不包含外面的标签,但包括换行),也可以设置内容:
<body>
<div id="text">
Hello
<b>World</b>
</div>
</body>
<script>
elem = document.getElementById('text');
console.log(elem.innerHTML);
</script>
注意
下面的语句是对 HTML 的重写(移除旧的内容写入新的内容),两个语句等价:
elem.innerHTML += "...";
elem.innerHTML = elem.innerHTML + "...";
4.3 outerHTML
outerHTML
可以获取完整的 HTML (包含外面的标签):
<body>
<div id="text">
Hello
<b>World</b>
</div>
</body>
<script>
elem = document.getElementById('text');
console.log(elem.outerHTML);
</script>
4.4 textContent
textContent
可以获取纯文本:
<div id="news">
<h1>Headline!</h1>
<p>Martians attack people!</p>
</div>
<script>
// Headline! Martians attack people!
alert(news.textContent);
</script>
假设有一个用户输入的字符串,我们希望将其显示出来。
- 使用
innerHTML
,我们将其“作为 HTML”插入,带有所有 HTML 标签。 - 使用
textContent
,我们将其“作为文本”插入,所有符号(symbol)均按字面意义处理。
<div id="elem1"></div>
<div id="elem2"></div>
<script>
let name = prompt("What's your name?", "<b>Winnie-the-Pooh!</b>");
elem1.innerHTML = name;
elem2.textContent = name;
</script>
在大多数情况下,我们期望来自用户的文本,并希望将其视为文本对待。我们不希望在我们的网站中出现意料不到的 HTML。
4.5 hidden
hidden
属性可以设置元素是否隐藏,下面的代码使用定时函数设置了标签是否可见,实现闪烁的效果:
<body>
<div id="blink">I'm blinking</div>
</body>
<script>
let timer = setInterval(() => {
let elem = document.querySelector('#blink');
elem.hidden = !elem.hidden;
}, 1000);
</script>
其他属性
value
—— input,select,textarea 标签的 valuehref
—— a 标签的 hrefid
—— 所有元素的 id 属性
<body>
<input type="text" name="fruit" id="fruit">
<input type="submit" name="submit" id="submit" onclick="show()">
</body>
<script>
let show = () => {
let elem = document.getElementById('fruit');
console.log(elem.value);
}
</script>
此时点击提交按钮可以显示出框内的文字内容(value)
5. 修改文档
DOM 修改是创建“实时”页面的关键。
5.1 创建元素
document.createELement(tag) —— 创建元素节点;
document.createTextNode(text) —— 创建文本节点;
let div = document.createElement('div');
let textNOde = document.createTextNode('text');
举个栗子
创建一个 div
标签:
let div = document.createElement('div');
div.id = 'alert';
div.innerHTML = '<strong>Hello</strong> guys!';
此时元素不能在浏览器中显示出来,需要插入。
5.2 插入方法
有以下常用方法:
- node.append(nodes or strings) :在
node
的末尾插入(放在内部) - node.prepend(nodes or strings) :在
node
的开头插入(放在内部) - node.before(nodes or strings):在
node
前面插入 - node.after(nodes or strings):在
node
后面插入 - node.replaceWith(nodes or strings):替换
node
的内容
如在 ol
标签插入:
将上面的 div
标签插入到 document.body
:
document.body.append(div);
5.3 节点移除
使用 node.remove()
移除节点:
下面的代码在 ol
的尾部追加了一个 li
标签,1s 后再删除 li
标签:
<body>
<ol>
<li>a</li>
<li>b</li>
<li>c</li>
</ol>
</body>
<script>
let li = document.createElement('li');
li.innerHTML = 'd';
document.getElementsByTagName('ol')[0].append(li);
let timer = setTimeout(() => li.remove(), 1000);
</script>
5.4 克隆节点
使用 elem.cloneNode(true)
创建元素的一个 “深” 克隆(复制所有特性和子元素);
使用 elem.cloneNode(false)
创建元素的一个 “深” 克隆;
let div = document.getElementsByName('div')[0];
let div2 = div.cloneNode(true); // 克隆消息
6. 样式和类
可以用 javascript 设置 style 属性:
let circle = document.querySelector('#circle');
let le = 0;
let timer = setInterval(() => {
le += 1;
circle.style.left = le + 'px';
if (circle.style.left == '650px') {
clearInterval(timer);
}
}, 5);
上面的 HTML 可以让绿色的圆匀速滚动,通过设置 elem.stle.xx
设置样式元素的属性。
可以查看 style:
console.log(document.body.style);
6.1 classList & className
使用 className
可以查看标签的所有类名;
使用 classList
可以增加 / 删除标签类名;
举个栗子:
<body>
<div class="class1 class2"></div>
</body>
<script>
let div = document.querySelector('div');
// 两个类: class1 class2
console.log(div.className);
div.classList.add('class3');
// 三个类: class1 class2 class3
console.log(div.className);
</script>
classList
常用方法:
elem.classList.add/remove(class)
—— 添加 / 移除elem.classList.toggle(class)
—— 类不存在就添加,否则移出elem.classList.contains(class)
—— 检查是否有给定类
6.2 应用例子
创建一个 div ,添加内容为 Hello,设置颜色为红色,背景为粉色:
let div = document.createElement('div');
div.innerHTML = 'Hello';
document.body.append(div);
div.style.color = 'red';
div.style.backgroundColor = 'pink';
更多推荐
所有评论(0)