1 BOM
1.1 BOM 的概念
(1) 什么是 BOM
BOM 全称 Browser Object Model,译为浏览器对象模型。
BOM 是浏览器为 JavaScript 提供的能够对浏览器进行相关操作的 API。
(2) BOM 的作用
1)弹出新浏览器窗口的能力。
2)移动、关闭和更改浏览器窗口大小的能力。
3)可提供WEB浏览器详细信息的导航对象。
4)可提供浏览器载入页面详细信息的本地对象。
5)可提供用户屏幕分辨率详细信息的屏幕对象;
6)支持Cookies。
(3) BOM 对象
浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构,一共有 5 个对象:
1)window
2)location
3)history
4)navigator
5)screen
1.2 window
① 弹框
alert() 警告框
confirm() 确认框,返回布尔值
prompt() 输入框,返回用户输入的内容
② 打开新窗口
// 打开新的空白页面窗口
window.open('');
// 在新窗口打开指定的页面
window.open('http://www.baidu.com');
// 在指定的窗口打开页面
window.open('http://www.baidu.com', '窗口的名字');
// 打开新窗口并指定窗口大小
window.open('./01-window的属性.html', '', 'width=400,height=300');
③ 页面滚动
滚动到页面中的某个坐标:
window.scrollTo( 0, 1000 );
// 设置滚动行为改为平滑的滚动
window.scrollTo({
top: 1000,
behavior: "smooth"
});
在窗口中按指定的偏移量滚动文档:
// 向下滚动一页:
window.scrollBy(0, window.innerHeight);
// 向上滚动一页:
window.scrollBy(0, -window.innerHeight);
// 平滑滚动
window.scrollBy({
top: 100,
left: 100,
behavior: "smooth"
});
④ 定时器
多次定时:
// 开启定时器 第一个参数可以是字符串,字符串中写代码
setInterval('console.log("hello world")', 2000);
// 开启定时器,第一个参数是回调函数,第二个参数间隔时间,单位是毫秒
setInterval(function(){
}, 2000);
// 开启定时器,回调函数可以有形参。
setInterval(function(val) {
}, 2000, '朦朦');
// setInterval 的返回值就是该定时器的唯一标识
// 取消定时器 需要指定定时器唯一标识
clearInterval(定时器ID)
单次定时:
// 开启单次定时 setTimeout 与 setInterval 的语法一模一样
setTimeout(function(){
}, 2000)
// 清除单次定时器
clearTimeout(单次定时器ID);
⑤ window 对象属性和方法总结
属性:
name 当前的窗口的名字,可读可写
innerWidth 视口宽度,只读
innerHeight 视口高度,只读
document
location
history
screen
navigator
方法:
alert() 警告框
confirm() 确认框
prompt() 输入框
open() 打开新窗口
close() 关闭窗口(窗口必须是被 open 打开的)
print() 开启打印预览
scrollTo() 滚动到页面指定位置
scrollBy() 滚动一定的距离
setInterval() 开启多次定时器
clearInterval() 清除多次定时器
setTimeout() 开启单次定时器
clearTimeout() 清除单次定时器
1.3 history
history 用于描述本窗口的历史记录。
属性:
length 获取本窗口历史记录的个数
方法:
back() 跳转到历史记录中的上一个页面
forward() 跳转到历史记录中的下一个页面
go() 跳转到历史记录中的上n个或下n个页面,指定数字作为参数,正数下n个,负数上n个
1.4 location
location 对象用于描述当前页面的地址信息
属性:(可读可写)
href 完整的地址
protocol 协议部分
host 主机名+端口号
hostname 主机名部分
port 端口号部分
pathname 路径部分
hash 锚点部分
search 查询部分
方法:
reload() 重新加载
assign() 页面跳转,保留历史记录
replace() 页面跳转,原网页不在历史记录保留
1.5 navigator
navigator 对象用于描述浏览器以及系统的信息。
属性:
userAgent 获取浏览器信息
1.6 screen
screen 对象用于描述屏幕信息
属性:
width 屏幕的宽度
height 屏幕的高度
2 DOM 操作
2.1 DOM 介绍
**MDN 文档对象模型手册:**developer.mozilla.org/zh-CN/docs/…
2.2 Node 节点
(1) 五大节点类型
元素节点 element
属性节点 attribute
文本节点 text
注释节点 comment
文档节点 document
(2) 节点的属性
nodeName 节点名,元素节点的节点名是标签名。
nodeValue 节点值。
nodeType 节点类型。
元素:1,属性:2,文本:3,注释:8,document:9
2.3 获取元素
① 通过 ID 名
document.getElementById('ID名');
返回对应的元素对象,如果没有找到该 ID 名的元素,返回
null
② 通过标签名
// document 的方法,从document的后代中查找(整个文档)
document.getElementsByTagName()
// 元素对象的方法,从指定元素的后代中查找
element.getElementsByTagName()
注意:
getElementsByTagName() 方法返回一个 HTMLCollection 对象,里面是所有满足条件的元素的集合,是个伪数组。
如果没有满足条件的元素,返回空的 HTMLCollection 对象。
③ 通过类名(了解,IE8 + 支持)
// document 的方法,从document的后代中查找(整个文档)
document.getElementsByClassName()
// 元素对象的方法,从指定元素的后代中查找
element.getElementsByClassName()
注意:
getElementsByClassName() 方法返回一个 HTMLCollection 对象,里面是所有满足条件的元素的集合,是个伪数组。
如果没有满足条件的元素,返回空的 HTMLCollection 对象。
④ 通过 name 属性值 (了解)
document.getElementsByName('name值');
返回一个 NodeList 对象,与 HTMLCollection 类似,也是伪数组,也是由满足条件的元素组成。
⑤ 通过选择器获取元素 (推荐)
// 从整个文档中获取
document.querySelector('css 选择器'); // 返回一个元素; 如果满足选择器条件的元素有多个,只返回第一个元素;如果没有满足条件的元素,返回 null。
document.querySelectorAll('css 选择器'); // 返回一个 NodeList 对象,是一个右所有满足条件的元素组成的集合,是个伪数组。
// 从某个元素的后代中获取
element.querySelector('css 选择器');
element.querySelectorAll('css 选择器');
⑥ 获取所有的元素
document.all
document.all 是一个语法糖,可以用来判断浏览器是 IE 还是 非IE
if (document.all) { // IE10 以及以下 alert('啊,我是IE浏览器'); } else { // chrome firefox safari opera Edge IE11 alert('嘿嘿,我不是IE浏览器!'); }
2.4 文档结构(元素关系)
(1) 节点树
parentNode 返回父节点
firstChild 第一个子节点
lastChild 最后一个子节点
childNodes 所有子节点组成的集合(NodeList 对象)
nextSibling 紧邻在后面的兄弟节点
previousSibling 紧邻在前面的兄弟节点
(2) 元素树
parentElement 返回父元素
firstElementChild 第一个子元素
lastElementChild 最后一个子元素
children 所有子元素组成的集合(HTMLCollection 对象)
nextElementSibling 紧邻在后面的兄弟元素
previousElementSibling 紧邻在前面的兄弟元素
所有的元素,除了 html 元素,父节点和父元素是一样的; html 元素没有父元素,但是父节点是 document
2.5 属性操作
(1) 读写内置属性
element.属性名;
element['属性名'];
(2) 读写自定义属性
// 读取属性的值
element.getAttribute('属性名');
// 设置属性的值
element.setAttribute('属性名', '值');
该方法不分属性是内置的还是自定义的,只要写在元素上的就可以操作!
(3) data-*
形式的自定义属性
<div data-name="" data-spm-age=""></div>
// 读写属性
divBox.dataset.name;
divBox.dataset.spmAge;
2.6 样式操作
(1) 操作行内样式
// 设置样式
ele.style.width = '100px'; // 带单位
ele.style.backgroundColor = '#f90'; // 带 - 的css属性名自动转为小驼峰
ele.style['background-color'] = 'red'; // 带 - 的css属性,可以使用 []
// 获取样式
ele.style.height;
ele.style.backgroundColor;
ele.style['border-width'];
注意:
.style
方式设置的样式,设置在行内。.style
方式获取元素某个样式,只能获取设置在行内的样式,其他地方的样式得到空字符串。
(2) 读取计算样式
所谓计算样式,指的是所有作用在元素上的样式,不论是设置到哪里; 哪怕没有设置该样式,还可以得到默认值。 元素的计算样式是只读的。
// 非 IE (包括 IE11 和 Edge)
window.getComputedStyle(元素).属性名
// IE 浏览器
元素.currentStyle.属性名
/**
* 兼容性得获取元素的计算样式
* @param element HTML 元素对象
* @param attrName string css的属性名
* @return css属性值
*/
function getStyle(ele, attrName) {
if (window.getComputedStyle) {
// 非IE浏览器(包括IE11 和 EDGE)
return getComputedStyle(ele)[attrName];
} else if (ele.currentStyle) {
// IE 浏览器
return ele.currentStyle[attrName];
}
}
(3) 通过类名操作
① className
ele.className; // 可读可写
② classList
ele.classList.add('类名'); // 在原有类型的基础上添加类名
ele.classList.remove('类名'); // 移除指定的类名,其他类名不受影响
ele.classList.toggle('类名'); // 如果存在类名就移除,如果没有类名就添加
ele.classList.length; // 属性,表示元素类名的个数
元素的 classList 属性可以得到一个对象,有类名组成的伪数组。
2.7 元素的文本内容(可读可写)
ele.innerHTML 读取或设置元素中的 html 内容(读取:标签代码能够读取到;设置:标签代码能被解析)
ele.outerHTML 相对于 innerHTML,读写的时候包括自己在内的 html 代码。
ele.innerText 读取元素中的文字内容(读取:标签代码被去掉;设置:标签代码变为实体)
ele.textContent 与innerText类似,保留内容中的缩进格式。
2.8 元素的尺寸位置(只读)
(1)元素的尺寸
offsetWidth 获取元素的宽度(内容宽+左右内边距+左右边框宽度)
offsetHeight 获取元素的高度(内容高+上下内边距+上下边框宽度)
clientWidth 获取宽度(内容宽+左右内边距)
clientHeight 获取高度(内容高+上下内边距)
scrollWidth 在 clientWidth 的基础上添加溢出内容的宽度
scrollHeight 在 clientHeight 的基础上添加溢出内容的高度
getBoundingClientRect() 返回一个对象,对象中有 width 属性和 height 属性,分别获取元素的宽高(同 offsetWidth 和 offsetHeight 一致)
快速获取 html 元素和 body 元素的方式:
document.documentElement
可以得到 html 根元素。
document.body
可以得到 body 元素。
获取视口的宽高:
window.innerWidth
和window.innerHeight
, 会算上滚动条自身的大小。
document.documentElement.clientWidth
和document.documentElement.clientHeight
(2) 元素的位置 (只读)
offsetLeft 获取元素在第一个定位的祖先元素上的 x 坐标; 如果祖先元素没有定位,参考根元素
offsetTop 获取元素在第一个定位的祖先元素山的 y 坐标; 如果祖先元素没有定位,参考根元素
clientLeft 元素左边框的宽度
clientTop 元素上边框的宽度
getBoundingClientRect() 返回对象,对象中具有如下属性
left: 元素在视口上的 x 坐标
top: 元素在视口上的 y 坐标
x: 同 left
y: 同 top
right: 元素右下角在视口上的 x 坐标
bottom: 元素右下角在视口上的 y 坐标
(3) 内容的位置(可读可写)
scrollLeft 内容向左偏移的距离
scrollTop 内容向上偏移的距离
内容可以滚动的生效前提: 元素的
overflow
属性的值不是visible
。
2.9 节点(元素)的创建添加删除替换克隆
(1) 创建元素节点
document.crateElement('标签名')
方法返回创建好的元素对象; 新创建的元素不会出现在文档结构中。
(2) 添加子节点
parentElement.appendChild(新节点); // 新节点会作为父元素的最后一个节点
parentElement.insertBefore(新节点,旧节点); // 指定位置添加子节点;新节点出现在旧节点的前面
(3) 删除子节点
parentElement.removeChild(要删除的节点); // 删除指定的子节点
(4) 替换子节点
parentElement.replaceChild(新节点,旧节点);
(5) 节点克隆
ele.cloneNode(true); // 返回元素的克隆版, 参数指定为 true,连同元素的内容以及后代一起克隆;默认是 false,只克隆元素本身不包括内容和后代
2.10 documnt 对象
document 对象表示整个文档,不是元素,是节点; document 是 html 根元素的父节点。
属性:
lastModified 代码最后一次修改时间(只读)
title 页面标题(可读可写)
documentElement 获取 html 根元素(只读)
body 获取 body 元素(只读)
head 获取 head 元素(只读)
all 获取所有元素的集合,返回 HTMLCollection 对象。(只读)
方法:
write() 将内容写入文档流
2.11 documentFragment 对象
(1) 创建 documentFragment 对象
document.createDocumentFrament(); // 该方法返回一个新创建的 documentFragment 对象
(2) documentFragment 对象的特点
documentFragment 对象也是一种节点,nodeType 是 11。
documentFragment 对象不会出现在页面结构中,但是可以作为一个容器拥有子节点。
把 documentFragment 对象作为子节点添加到一个页面的元素中,documentFragment 对象会把自己的子节点作为元素的子节点。
(3) documentFragment 对象的应用
- 批量添加子节点,可以先把子节点添加到 documentFragment 对象中,再把documentFragment 对象一次性添加要添加的元素中。可以提高浏览器渲染效率。
- 借助于documentFragment 对象实现元素的翻转。
3 HTML DOM
3.1 表单相关元素
① form 元素
方法:
submit() form 元素对象调用该方法,表单会提交
reset() form 元素对象调用该方法,表单会重置
② 文本输入框和文本域(input 和 textarea)
方法:
focus() 获取焦点
blur() 失去焦点
select() 选中里面的文字
③ select 元素
属性:
value 获取选中的选项的 value 值
length 获取拉下选选项的数量
selectedIndex 获取选中的选项的索引
方法:
add(option元素) 添加一个 option 元素
remove(index) 删除一个选项,指定要删除选项的索引
创建 option 元素的方式:
new Option(中间的内容,value值)
3.2 表格相关元素
① table 元素
属性:
rows 获取表格中所有 tr 元素的集合
cells 获取表格中所有 td 或 th 元素的集合
方法:
insertRow() 向表格中插入一行,可以指定位置
deleteRow() 删除一行,指定要删除行的索引
② tableRow 元素(tr 元素)
属性:
rowIndex 返回当前行的索引
cells 返回本行内所有单元格集合
方法:
insertCell() 向行内添加一个单元格,可以指定位置
deleteCell() 删除行内的一个单元格,指定要删除单元格的索引
③ tableCell 元素 (td 或 th)
属性:
cellIndex 本单元格在行里的索引
3.3 快速创建 img 元素
new Image();
所创建的 img 元素与 document.createElement('img') 一样。
4 事件
4.1事件的监听(绑定)方式
① 第一种方式 把事件作为标签的属性
<button onclick="js代码..."></button>
② 第二种方式 把事件作为元素对象的方法
// 获取到元素对象
// 给元素对象监听事件
element.onclick = function(){
js 代码....
}
③ 第三种方式 使用 AddEventListener
// 获取到元素对象
// 给元素对象监听事件
element.addEventListener('click', function(){
js 代码...
});
第三种方式监听事件的特定:
- 事件名是不包括
on
的,前两种监听事件的方式需要在事件名前面添加on
,addEventListener 方式不需要添加on
。- 前两种方式同一种事件无法监听多次;addEventListener 方式可以监听多次同一种事件。
- addEventListener 方式需要 IE8 以上浏览器支持; 前两种兼容性非常好。
4.2 解除事件的监听(绑定)
① 解除第一种方式和第二种方式监听的事件
// 重新设置事件,覆盖前面
element.onclick = null;
② 解除第三种方式监听的事件
// 使用方法
element.removeEventListener('click', 回调函数名);
注意: addEventListener 监听的事件如果将来打算取消监听,回调函数就不能是匿名的。
4.3 事件流
事件的触发会经过三个阶段:
捕获阶段: 从 window 开始到 document,到 html,到 body 一直到目标元素(发生事件动作的元素)
目标阶段: 找到目标元素了,标志着捕获阶段的结束,冒泡阶段的开始。
冒泡阶段: 从目标元素开始,层层向上,一直到 body、html、document、window。
给元素监听了事件,事件默认会在冒泡阶段触发!
addEventListener()
第三个参数如果设置为 true,表示该事件在捕获阶段触发!第一种和第二种监听事件的方式只能在冒泡阶段触发。
4.4 事件回调函数中 this 的指向
- this 的指向规则,仍然是谁调用了方法,方法中的 this 就执行谁。
- 触发事件的元素调用了对应的回调函数。 事件回调函数中的 this 指向触发事件的元素!
4.5 常用事件
(1) 鼠标事件
click 单击
dblclick 双击
contextmenu 右击
mousedown 鼠标按键按下
mouseup 鼠标按键抬起
mousemove 鼠标按键移动
mouseenter 鼠标进入元素(IE9+) 代替 mouseover
mouseleave 鼠标离开元素(IE9+) 代替 mouseout
(2) 键盘事件
keydown 键盘按键按下,所有按键都可以触发
keyup 键盘按键抬起,所有按键都可以触发
keypress 键盘按键按下,但是只有非控制字符按键才可以触发
如何获取到按的是哪个按键?
- 通过
event.keyCode
属性得到按键对应的 acsii 值。keydown
获取的按键是不区分字母大小写,keypress
可以区分字母按键的大小写。
(3) 文档事件
load 页面中所有的一切加载完毕,触发;通常监听给 window 元素。
DOMContentLoaded 页面中的元素加载完毕,触发;通常监听给 window 元素。推荐。
beforeunload 文档关闭的时候触发。
load 事件和 DOMContentLoaded 事件的区别:
- DOMContentLoad 只要页面中所有的元素加载完毕就可以触发,而 load 事件必须等到页面中所有的一切(包括外部文件,如图片)加载完毕才触发。
- DOMContentLoaded 只能使用 addEventListener 方式监听。
(4) 表单事件
submit 监听给 form 元素,当表单被提交的时候,触发事件。
reset 监听给 form 元素,当表单被重置的时候,触发事件。
focus 监听给表单控件,当获取焦点的时候触发事件。
blur 监听给表单控件,当失去焦点的时候触发事件。
select 监听给可输入元素,当里面的内容被选中,触发事件。
change 监听给表单控件,更适合复选框、单选按钮、下拉选项,有变化就触发。
输入框监听 change 事件,触发条件:
- 输入框内容要改变。
- 输入框要失去焦点。
(5) 图片事件
load 监听给 img 元素,等到图片加载完毕。
error 监听给 img 元素,图片加载失败。
(6) 其他事件
scroll 监听给有滚动条的元素或window,一滚动就不停地触发。
resize 监听给 window,视口尺寸发生变化。
获取页面整体滚动(偏移)的距离:
document.documentElement.scrollTop || document.body.scrollTop
4.6 Event 对象
(1) 获取 Event 对象
给事件的回调函数,设置一个形参,自动获取本次事件触发对应的事件对象。
(2) 鼠标事件对象 MouseEvent 的属性和方法
clientX / clientY 获取鼠标在视口上的位置
pageX / pageY 获取鼠标在整个文档(整个页面)上的位置
screenX / screenY 获取鼠标在屏幕上的位置
offsetX / offsetY 获取鼠标在目标元素上的位置
button 获取鼠标按的哪个按键; 值是 0 表示左键、值是 1 表示中间的滚轮、值是 2 表示右键
(3) 键盘事件对象 KeyBorardEvent 的属性和方法
keyCode 获取按键的ascii值
which 同 keyCode
key 获取按键的值
(4) 所有的事件对象都有的属性和方法
type 获取事件名
target 获取目标元素
timeStamp 获取触发事件的那一刻距离打开页面的那一刻相差的毫秒数
stopPropagation() 阻止冒泡
preventDefault() 阻止浏览器默认行为
(5) 阻止事件冒泡
在事件的回调函数中执行:
event.stopPropagation();
注意:
return false
在原生 js 中不能阻止冒泡。
(6) 浏览器的默认行为
① 浏览器有哪些默认行为
在页面中右击,出现菜单
超连接点击跳转
表单的提交和重置
等
② 阻止浏览器默认行为
在事件的回调函数中调用语句:
event.preventDefault();
注意:
如果是使用第二种方式监听事件(把事件作为元素对象的方法),回调函数中写
return false
同样可以阻止默认行为,与event.preventDefault()
功效一致!
4.6 事件委托
如何实现事件委托:
把事件委托监听给要监听事件元素 的祖先元素,触发事件的时候,判断目标元素是否是监听事件的元素,如果是就执行相关操作,不是什么也不做。
事件委托解决什么问题:
事件委托主要解决新增的元素也能监听上事件。
5 深入分析 DOM 对象
5.1 元素对象的原型链关系
div元素对象 -> HTMLDivElement.prototype -> HTMLElement.prototype -> Element.prototype -> Node.prototype -> EventTarget.prototype -> Object.prototype
5.2 事件对象的原型链关系
鼠标事件对象 -> MouseEvent.prototype -> UIEvent.prototype -> Event.prototype -> Object.prototype
5.3 HTMLCollection 和 NodeList 的区别
NodeList 类型的对象:
- NodeList 对象是节点组成的集合,成员中可以有元素节点、属性节点等所有类型的节点。
- 具有 forEach 方法。
- 该对象是静态的,获取完对象再添加元素,对已经获取的对象没有影响。
querySelectorAll()
、getElementsByName()
的返回值和childNodes
的属性值 得到一个 NodeList 对象。
HTMLCollection 类型的对象:
- HTMLCollection 对象是元素组成的集合,成员中只能是元素。
- 没有 forEach 方法
- 该对象是动态的,获取完对象再添加元素,对象中包含新的元素。
getElementsByTagName()
和getElementsByClassName()
的返回值和children
的属性值可以得到一个 HTMLCollection 对象。