JavaScript学习笔记(八)-Web APIs & DOM
1. API 和 Web API
1. API
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
简单理解:API 是给我们提供的一种工具,以便能更轻松的实现想要完成的功能。
2. Web API
Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API(BOM 和 DOM)。
比如想要浏览器弹出一个警示框,直接使用 alert(‘弹出’)。
Web API 主要是针对于浏览器提供的接口,主要针对于浏览器做交互效果。
Web API 一般都有输入和输出(函数的传参和返回值),Web API 很多都是方法(函数)。
因为 Web API 很多,所以我们将这个阶段称为 Web APIs。
MDN 详细:Web API 简介 - 学习 Web 开发 | MDN
2. DOM 简介
1. 什么是 DOM
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML 或者 XML)的标准编程接口。
W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。
2. DOM 树
- 文档:一个页面就是一个文档,DOM 中使用 document 表示
- 元素:页面中的所有标签都是元素,DOM 中使用 element 表示
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM 中使用 node 表示
DOM 把以上内容都看做是对象
3. 获取元素
1. 如何获取页面元素
DOM 在实际开发中主要用来操作元素
获取页面中的元素可以使用以下几种方式:
- 根据 ID 获取
- 根据标签名获取
- 通过 HTML5 新增的方法获取
- 特殊元素获取
2. 根据 ID 获取
MDN 详解:document.getElementById - Web API 接口参考 | MDN
getElementById() 方法可以获取带有 ID 的元素对象
语法:
1 | var element = document.getElementById('id'); |
**
element
**是一个 Element 对象。如果当前文档中拥有特定 ID 的元素不存在则返回 null.**
id
**是大小写敏感的字符串,代表了所要查找的元素的唯一 ID.
3. 根据标签名获取
MDN 详解:Document.getElementsByTagName() - Web API 接口参考 | MDN
getElementsByTagName() 方法可以返回带有指定标签名的 对象集合。
语法:
1 | var elements = document.getElementsByTagName('标签名'); |
示例:
1 |
|
- 如果页面中只有一个 li,返回的还是伪数组的形式
- 如果页面中没有这个元素,返回的是一个空的伪数组
注意:父元素必须是 单个对象(必须指明是哪一个元素对象)获取的时候不包括父元素本身
4. 根据 HTML5 新增的方法获取
1. 根据类名返回元素对象集合
MDN 详解:Document.getElementsByClassName() - Web API 接口参考 | MDN
语法:
1 | var elements = document.getElementsByClassName('类名'); |
- elements 是一个实时
集合
,包含了找到的所有元素。 - names 是一个字符串,表示要匹配的类名列表;类名通过空格分隔
- getElementsByClassName 可以在任何元素上调用,不仅仅是 document。 调用这个方法的元素将作为本次查找的根元素.
2. 根据选择器返回元素对象
MDN 详解:document.querySelector() - Web API 接口参考 | MDN
语法:
1 | var element = document.querySelector('CSS选择器'); |
- 里面的选择器需要加符号
- 类选择器加 ‘.’,例如:document.querySelector(‘.box’);
- ID 选择器加 ‘#’,例如:document.querySelector(‘#box’);
3. 返回指定选择器的所有元素对象集合
MDN 详解:Document.querySelectorAll - Web API 接口参考 | MDN
语法:
1 | var elementList = document.querySelectorAll('选择器'); |
5. 获取特殊元素
1. 获取 body 元素
1 | var bodyElement = document.body; |
2. 获取 html 元素
1 | var htmlElement = document.documentElement; |
4. 事件基础
1. 事件概述
JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。
简单理解:触发 — 响应机制。
网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,可以在用户点击某个按钮时产生一个事件,然后去执行某些操作。
2. 事件三要素
- 事件是由三部分组成,事件源,事件类型,事件处理程序,称为事件三要素
1 | <body> |
3. 执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
1 | <body> |
4. 常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
5. 操作元素
JavaScript 的 DOM 操作可以改变网页内容、结构和样式,我们可以利用 DOM 操作元素来改变元素里面的内容、属性等。
1. 改变元素内容
1 | element.innerText; |
从起始位置到终止位置的内容,但它去除 html 标签,同时空格和换行也会去掉
1 | element.innerHTML; |
起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行
实例:
1 | <body> |
2. 常用元素的属性操作
- innerText、innerHTML 改变元素内容
- src、href
- id、alt、title
点击切换图片案例:
1 | <body> |
3. 表单元素的属性操作
利用 DOM 可以操作如下表单元素的属性:
type、value、checked、selected、disabled
1 | <body> |
显示隐藏密码案例:
核心思路:
- 点击眼睛按钮,将密码框类型改为文本框类型就可以看见里面的面
- 一个按钮两个状态,点击一次,切换为文本框,再点击一次切换为密码框
- 算法:利用一个 flag 变量,来判断 flag 的值,如果是 0 就切换为文本框,flag 设置为 1;如果是 1 就切换为密码框,flag 设置为 0
1 | <body> |
4. 样式属性操作
可以通过 JS 修改元素的大小、颜色、位置等样式。
- element.style 行内样式操作
- element.className 类名样式操作
1. 使用 element.style 修改元素样式,在样式比较少,或者功能简单的情况下使用
1 | <head> |
注意:
- JS 里面的样式采取驼峰命名法,比如 fontSize、backgroundColor
- JS 修改 style 样式操作,产生的是行内样式,css 权重比较高
2. 通过修改元素的 className 更改元素的样式,适合样式较多或者功能复杂的情况
注意:
- class 是保留字,因此使用 className 来操作元素类名属性
- className 会直接更改元素的类名,会覆盖原先的类名
1 | <head> |
5. 排他思想(算法)
如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想算法
- 将所有元素全部清除样式(排除他人)
- 给当前元素设置样式(留下自己)
- 注意顺序不能颠倒
1 | <body> |
6. 自定义属性的操作
1. 获取属性值
- element.属性 获取内置属性值(元素本身自带的属性)
- element.getAttribute(‘属性’) 主要获取自定义的属性,由我们自己定义的属性
1 | <body> |
1 | <body> |
2. 设置属性值
element.属性 = ‘值’ 设置内置属性值
element.setAttribute(‘属性’, ‘值’); 主要设置自定义的属性
1 | <body> |
1 | <body> |
3. 移除属性
element.removeAttribute(‘属性’) 移除属性
1 | <body> |
4. H5 自定义属性
自定义属性的目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
自定义属性的获取是通过 getAttribute(‘属性’)
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
为此,H5 为我们新增了自定义属性
1. 设置 H5 自定义属性
H5 规定自定义属性为 data- 开头作为属性名并且赋值。
比如:<div data-index="1"></div>
或者使用 JS 设置:element.setAttribute('data-index', 2)
1 | <body> |
1 | <body> |
2. 获取 H5 自定义属性
- 兼容性获取
element.getAttribute('data-index')
- H5 新增
element.dataset.index
或者element.dataset['index']
ie 11 才开始支持
1 | <body> |
6. 节点操作
1. 为什么学节点操作
获取元素通常使用两种方式:
- 利用 DOM 提供的方法获取元素
document.getElementById()
document.getElementByTagName()
document.querySelector()
等- 逻辑性不强、繁琐
- 利用节点层级关系获取元素
- 利用父子兄节点关系获取元素
- 逻辑性强,但是兼容性稍差
这两种方式都可以获取元素节点,节点操作会更简单一些。
2. 节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等),在 DOM 中,节点使用 node 来表示
HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
一般地,节点至少拥有 nodeType(节点类型)、nodeName(节点名称)和 nodeValue(节点值)这三个基本属性。
- 元素节点 nodeType 为 1
- 属性节点 nodeType 为 2
- 文本节点 nodeType 为 3(文本节点包括文字、空格、换行等)
在实际开发中,节点操作主要操作的是元素节点
3. 节点层级
利用 DOM 数可以把节点划分为不同的层级关系,常见的就是 父子兄层级关系
1. 父节点
1 | node.parentNode; |
- parentNode 属性可返回某节点的父节点,注意是 最近的一个父节点
- 如果指定的节点没有父节点则返回 null
1 | <body> |
2. 子节点
1 | 1. parentNode.childNodes(标准) |
parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。
返回值里面包含了所有的子节点,包括元素节点,文本节点等。
如果只想要获得里面的元素节点,则需要专门处理。所以一般不提倡使用 childNodes
1 | var ul = document.querySelector('ul'); |
1 | 2. parentNode.children(非标准) |
parentNode.children 是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(重点)
虽然 children 是一个非标准,但是得到了各个浏览器的支持,可以放心使用
1 | 3. parentNode.firstChild |
firstChild 返回第一个子节点,找不到则返回 null。同样,也是包含所有的节点
1 | 4. parentNode.lastChild |
lastChild 返回最后一个子节点,找不到则返回 null。同样,也是包含所有的节点
1 | <body> |
1 | 5. parentNode.firstElementChild |
parentNode.firstElementChild 返回第一个子节点,找不到则返回 null。
1 | 6. parentNode.lastElementChild |
parentNode.lastElementChild 返回最后一个子节点,找不到则返回 null。
注意:这两个方法有兼容性问题,IE9 以上才支持
1 | <body> |
3. 兄弟节点
1 | 1. node.nextSibling |
nextSibling 返回当前元素的下一个兄弟节点,找不到则返回 null。同样,也是包含所有的节点。
1 | 2. node.previousSibling |
previousSibling 返回当前元素上一个兄弟节点,找不到则返回 null。同样,也是包含所有的节点。
1 | <body> |
1 | 3. node.nextElementSibling |
nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回 null。
1 | 4. node.previousElementSibling |
previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回 null。
1 | <body> |
注意:这两种方法有兼容性问题,IE9 以上才支持。
4. 创建节点
1 | document.createElement('tagName'); |
document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为 动态创建元素节点。
1 | <body> |
4. 添加节点
1 | 1. node.appendChild(child) |
node.appendChild(child) 方法将第一个节点添加到指定父节点的子节点列表 末尾。类似于 css 里面的 after 伪元素。
1 | 2. node.insertBefore(child, 指定元素) |
node.insertBefore() 方法将一个节点添加到父节点的指定子节点 前面。类似于 css 里面的 before 伪元素。
1 | <body> |
想要页面添加一个新的元素分为两步:
- 创建元素
- 添加元素
5. 删除节点
1 | node.removeChild(child); |
node.removeChild() 方法从 DOM 中删除一个子节点,返回删除的节点
案例:
1 | <body> |
6. 复制节点(克隆节点)
1 | node.cloneNode(); |
node.cloneNode() 方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点
1 | <body> |
注意:
- 如果括号参数为空或者为 false,则是浅拷贝,即只克隆节点本身,不克隆里面的子节点。
- 如果括号参数为 true,则是 深度拷贝,会复制节点本身以及里面所有的子节点。
7. 三种动态创建元素区别
document.write()
element.innerHTML
document.createElement()
1 | <body> |
1 | <body> |
区别
document.write 直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
innerHTML 将内容写入某个 DOM 节点,不会导致页面全部重绘
innerHTML 创建多个元素效率更高(不使用拼接字符串,采取数组形式拼接),结构稍微复杂
createElement() 创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML 效率要比 createElement 高
7. DOM 重点核心
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML 或者 XML)的标准编程接口。
W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。
- 对于 JavaScript,为了能够使 JavaScript 操作 HTML,JavaScript 就有了一套自己的 DOM 编程接口
- 对于 HTML,DOM 使得 HTML 形成一颗 DOM 树,包含 文档、元素、节点
我们获取过来的 DOM 元素是一个对象(object),所以称为 文档对象模型
关于 DOM 操作,我们主要针对于元素的操作。主要有 创建、增、删、改、查、属性操作、事件操作。
1. 创建
- document.write
- innerHTML
- createElement
2. 增
- appendChild
- insertBefore
3. 删
- removeChild
4. 改
主要修改 DOM 的元素属性,DOM 元素的内容、属性,表单的值等
- 修改元素属性: src、href、title 等
- 修改普通元素内容: innerHTML、innerText
- 修改表单元素: value、type、disabled 等
- 修改元素样式: style、className
5. 查
主要获取查询 DOM 的元素
- DOM 提供的 API 方法: hetElementById、getElementsByTagName 古老方法,不太推荐使用
- H5 提供的新方法: querySelector、querySelectorAll 推荐使用
- 利用节点操作获取元素: 父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 推荐使用
6. 属性操作
主要针对于自定义属性
- setAttribute: 设置 DOM 的属性值
- getAttribute:得到 DOM 的属性值
- removeAttribute: 移除属性
7. 事件操作
给元素注册事件,采取 事件源.事件类型 = 事件处理程序
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |