BOM是由一系列相关对象构成,每个对象都提供了很多方法和属性。
在 BOM 里最重要的对象有 5 个, 分别如下:
location其用来保存当前网页位置的信息。
--- reload() 方法
为了防止无限快速循环,我们设置一个定时器延迟调用 reload。
location.reload()
方法用来刷新当前页面,就像刷新按钮一样。
- setTimeout(function () {
- window.location.reload();
- }, 3000);
直接将网页地址赋值给 Location
可以直接修改location的值。
window.location = 'https://www.youkeda.com';
History 允许操作浏览器的曾经在标签页或者框架里访问的会话历史记录,由这个名称我们得知,History 会存储该窗口的历史记录。
在实际存储中用到的数据结构和数组特别类似,叫做栈。
back() 和 forward() ,分别对应到浏览器左上角的返回和前进按钮。
Navigator 表示用户代理的状态和标识,也就是浏览器基本信息,在这里面我们需要了解一个属性 --- userAgent,代表当前浏览器的用户代理。
文档对象模型 (DOM) 可以将 web 页面 与 脚本或编程语言 连接起来.
重点
1. web 页面
这里的 web 页面,也就是之前我们用 HTML 和 CSS 绘制的页面,也称作为文档
2. 脚本或编程语言 为什么这里不直接说将 Web 页面和 Javascript 语言连接起来,而要绕一下说脚本或编程语言呢?
因为 DOM 是一种规范,或者是一种约定,只要遵循这个规范,那么无论是
Javascript
,还是python
,或者java
都可以被连接起来。
web 网页最终会映射为一棵 DOM 树,DOM 树连接网页和 Javascript 语言。
DOCUMENT 元素会存在全局变量 window 下面,可以直接访问:
window.document;
选择器查询方法 --- querySelector()
- //基础筛选条件
- '.subtitle';
-
- //加强版本,加上父亲筛选, 筛选 main标签下面 -> class为core的节点下面 -> class为subtitle的节点
- 'main .core .subtitle';
document.querySelector('main .core .subtitle');
迭代查询
当我们得到 subtitle 元素后,我们还可以利用这个元素,继续筛选器内部元素,比如我们想筛选器内部的 a 标签。
- let subtitle = document.querySelector('main .core .subtitle');
- console.log(subtitle.querySelector('a'));
查询上面 HTML 中的所有 input 节点.
document.querySelectorAll('input');
查询返回的是一个类数组,我们可以直接通过索引访问。
类数组,顾名思义类似数组形式,(可以通过索引访问的对象我们都可以称之为类数组),从 JSConsole 中我们实际得到的是NodeList对象。
getElementById(): 根据 id 查询某个节点
getElementsByClassName(): 根据 class 查询多个节点
getElementsByTagName(): 根据 标签名 查询多个节点
querySelector 查询出来的元素是拷贝的原始数据,不会再随着页面 DOM 节点的改变而变化 get 系列方法 查询出来的元素就是原始数据,所以会随着页面的 DOM 节点的改变而变化
- <html>
- ……
- html>
-
- <div class="subtitle">
- ……
- div>
-
- <a class="free-bright">免费靓号a>
-
- <input class="password" type="pasworkd" placeholder="请输入密码" />
Element
, 不同的地方在于nodeType
分别为1, 2, 3
。nodeName
获取标签名称nodeValue
获取文本内容nodeName
取得属性 Key,用nodeValue
取得属性 Valueattributes
可以获取元素节点的所有属性,得到的结果是一个字典,通过属性 Key 获取对应的特性节点。属性 | 总结 | |
---|---|---|
outerHTML | 整个 DOM 的 HTML 代码 | |
innerHTML | DOM 内部 HTML 代码 | |
innerText | DOM 内部纯文本内容 |
- let divDom = document.querySelector('div#test');
- console.log(divDom.firstChild, divDom.lastChild);
- console.log('-----');
- console.log(divDom.childNodes);
- console.log('-----');
- console.log(divDom.parentNode);
属性 | 值 | 总结 |
---|---|---|
firstChild | 指定节点的第一个子节点 | |
lastChild | 指定节点的最后一个子节点 | |
childNodes | 指定节点的子节点的集合 | |
parentNode | 指定节点在 DOM 树中的父节点 |
lastChild 的值为 text
实际上就是换行符。
属性 | 类型 | 值 | 总结 |
---|---|---|---|
classList | DOMTokenList 类数组 | ['test'] | classList 数组方式存储所有的 class 名称 |
style | CSSStyleDeclaration | color 属性为rgb(255, 51, 0) | 对象或字典的方法存储 CSSStyle |
HTML 提供一种数据属性的标准,利用data-*
允许我们在标准内于 HTML 元素中存储额外的信息。
有一些数据,,不一定是直接展示的,有可能字数是某种特效才展示,分类数据是动态更新时需要用到,可以利用data-*
来存储。
<article data-parts="3" data-words="1314" data-category="python"></article>
数据的获取:
- const article = document.querySelector('article');
- console.log(article.dataset);
dataset
是个 Map 对象,它是data-*
这个*
的Key-Value集合。
document.createElement(tagName)
此方法用于创建一个由标签名称 tagName 指定的 HTML 元素,也就是上节课提到的元素(标签)节点。
如果想创建一个div
标签,我们可以使用:
const div = document.createElement('div');
创建文本方法**document.createTextNode(),
这个div
标签内部,添加纯文本内容
把txt
添加到div
中,把div
添加到body
中
- const div = document.createElement('div');
- const txt = document.createTextNode('优课达-学的比别人好一点');
- div.appendChild(txt);
- document.body.appendChild(div);
appendChild(newNode)
inserBefore(newNode, referenceNode)
此方法和appendChild()
刚好相反,appendChild
是在所有儿子节点之后添加,inserBefore
是在某个目标儿子节点之前添加。
insertBefore(newNode, referenceNode)
,需要两个参数,newNode
表示新节点,referenceNode
表示目标节点,也就是新节点插入到目标节点之前。
img.setAttribute('style', 'width: 100%; height: 100%;');
单独设置某些属性,如下代码:
dom.style.color = 'xxxx';
**setAttribute()**不仅仅可以设置style
之外,所有 HTML 属性都能用他设置,比如id
, src
, type
, disabled
, etc...
classList
能获取到 DOM 上所有的类,所以我们也可以把样式写成css,然后再添加或删除class。
使用innerHTML = ''
清空select
节点所有的后代内容。
也可以利用innerHTML给某个元素添加内容。
- function createDisease(txt) {
- const dom = document.createElement('li');
-
- // 我们可以直接用innerHTML设置其纯文本
- dom.innerHTML = txt;
- return dom;
- }
- // 监听Input输入事件
- dom.addEventListener("input", function () {});
-
- // 监听鼠标放置,移动事件
- dom.addEventListener("mouseover", function () {});
-
- // etc...
DOM 可以通过 addEventListener(eventName, callback)
绑定eventName
事件。
focus: 表单组件(Input, Textarea, etc..)获取焦点事件 blur: 表单组件(Input, Textarea, etc..)失去焦点事件
click: 点击事件 dblclick: 双击事件 mousedown: 在元素上按下任意鼠标按钮。 mouseenter: 指针移到有事件监听的元素内。 mouseleave: 指针移出元素范围外(不冒泡)。 mousemove: 指针在元素内移动时持续触发。 mouseover: 指针移到有事件监听的元素或者它的子元素内。 mouseout: 指针移出元素,或者移到它的子元素上。 mouseup: 在元素上释放任意鼠标按键。
keydown: 键盘按下事件 keyup: 键盘释放事件
scroll: 文档滚动事件 resize: 窗口放缩事件
load: 资源加载成功的事件
- // 默认是未点击喜欢
- let hasLike = false;
-
- const likeBtn = document.querySelector(".like-btn");
- likeBtn.addEventListener("click", function () {
- // 点击事件
- hasLike = !hasLike;
- console.log(hasLike);
- });
1.点击事件触发监听事件
2.冒泡找到其父亲节点,触发父亲节点的监听事件
3.依次冒泡直到html根元素为止。
- // ......省略
- likeBtn.addEventListener('click', function(e) {
- // 点击事件
- e.stopPropagation()
捕获和冒泡是完全相反的,冒泡是从当前元素沿着祖先节点往上冒泡,而捕获是从根 HTML 节点开始依次移动到当前元素。
我们上面使用的addEventListener
是在冒泡阶段监听事件,如果想在捕获阶段监听事件,我们需要传递第三个参数为true
, 代码如下
dom.addEventListener('click', function() {}, true);
在大量子元素中单击任何一个都可以运行一段代码,可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。
将
- const box = document.querySelector('.box');
- const imgArr = box.children;
-
- for (let i = 0; i < imgArr.length; i++) {
- imgArr[i].addEventListener('click', function() {
- document.body.style.backgroundImage = `url(${imgArr[i].src})`;
- });
- }
修改为
- const box = document.querySelector('.box');
-
- box.addEventListener('click', function(e) {
- // 注意box区域比img大,如果点击在空白间隔区域,那么返回的节点将不会是IMG,需要特殊处理一下
- if (e.target.nodeName === 'IMG') {
- document.body.style.backgroundImage = `url(${e.target.src})`;
- }
- });
mouseenter: 指针移到有事件监听的元素内。
mouseleave: 指针移出元素范围外(不冒泡)。
mousemove: 指针在元素内移动时持续触发。
mouseover: 指针移到有事件监听的元素或者它的子元素内。
mouseout: 指针移出元素,或者移到它的子元素上。
1. mousemove
这个是鼠标移动事件,比较简单
2. mouseenter/mouseleave
这个是鼠标进入和离开事件,但是仅仅只作用于当前 DOM 节点,不会作用于其后代节点
3. mouseover/mouseout
这个也是鼠标进入和离开事件,但和
enter/leave
不同的是:此事件除了作用于当前 DOM 节点,也会同时作用于其后代节点
获取焦点和失去焦点两个事件 --- focus 和 blur。
监听元素内容变化 --- input 和 change。
- const nick = document.querySelector('input.nick');
- nick.addEventListener('input', function() {
- console.log('-----input');
- console.log(nick.value);
- });
-
- nick.addEventListener('change', function() {
- console.log('-----change');
- console.log(nick.value);
- });
事件 | 介绍 | 案例 |
---|---|---|
change | 当用户提交对元素值的更改时触发; change 事件不一定会对元素值的每次更改触发 | 1. checkbox 值修改以后 2. select 选择后 3. input 内容修改并失去焦点 |
input | 只要 value 值修改就会触发 |
网页每次滚动到底部,会加载新内容,再次滚动到底部,又会加载新内容。
2. 动态效果
滚动一般用于展示一些动态效果,比如知乎头部
滚动事件,事件名称为 --- scroll。
keyboardEvent
KeyboardEvent
对象描述了用户与键盘的交互。每个事件都描述了用户与一个按键(或一个按键和修饰键的组合)的单个交互。