# JavaScript BOM 基础部分
BOM (Browser Object Model), 即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心是 window

window 对象是浏览器的顶级对象,它具有双重角色
- 他是 JS 访问浏览器窗口的一个接口
- 它是一个全局对象,定义在全局作用域中的变量,函数都会变成 window 对象的属性和方法
# window 对象的常见对象
# 窗口加载事件
window.onload 是窗口 (页面) 加载事件,, 当文档内容完全加载完成会触发该事件 (包括图像,脚本文件,CSS 文件等), 就调用的处理函数
注意 :
- 有了 window.onload 就可以把 JS 代码写到网页元素的上方,因为 onload 是等页面内容全部加载完毕,再去执行处理函数
- window.onload 传统注册事件只能写一次,如果有多个,会以最后一个 window.onload 为准
1 | window.addEventListener('load', function () { |
DOMContentLoaded 事件触发时,仅当 DOM 加载完成,不包括样式表,图片,flash 等等 (IE9 以上支持)
如果页面的图片很多的话,从用户访问当 onlick 触发可能需要较长的时间,必然影响用户的体验,此时用 DOMContentLoaded 时间比较合适
1 | window.addEventListener('DOMContentLoaded', function () { |
# 调整窗口大小事件
window.onresize 是调整窗口大小加载事件,当触发时就调用的处理函数
注意 :
- 只要窗口大小发生像素变化,就会触发这个事件
- 我们经常利用这个事件完成响应式布局,
window.innerWidth当前屏幕的宽度
1 | var div = document.querySelector('div'); |
# 定时器
window 对象给我们提供了 2 个定时器 :
setTimeout(),setInterval()
# setTimeout () 定时器
window.setTimeout (调用函数,[延迟的毫秒数]);
该定时器在定时器到期后执行调用函数
注意 :
- window 可以省略
- 这个调用函数可以直接写函数,或者写函数名或者采用字符串,== 函数名 ()== 三种形式,第三种不推荐
- 延迟的毫秒数省略默认是 0, 如果写,必须是毫秒
- 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符
1 | var timer = setTimeout(function () { |
window.clearTimeout(timeoutID)
停止 setTimeout () 定时器
注意 :
- window 可以省略
- 里面的参数就是定时器的标识符
1 | button.addEventListener('click', function () { |
# setInterval () 定时器
window.setInterval (回调函数,[间隔的毫秒数]);
setInterval () 方法重复调用一个函数,每隔这个事件,就去调用一次回调函数
注意 :
- window 可以省略
- 这个调用函数可以直接写函数,或者写函数名或者采取字符串
函数名()三种形式 - 间隔的毫秒数省略默认是 0, 如果写,必须是毫秒,表示每个多少毫秒就自动调用这个函数
- 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符
1 | var timer setInterval(function () { |
window.clearInterval(intervalID);
通过取消了先前通过调用 setTinterval () 建立的定时器
注意 :
- window 可以省略
- 里面的参数就是定时器的标识符
# this 指向问题
- 全局作用域或者普通函数中
this指向全局对象window( 注意定时器里面的this指向 window) - 方法中的
this指向调用这个方法的对象 - 构造函数中的
this指向实例对象
# JS 执行机制
# JS 单线程
JavaScript 语言的一大特点就是单线程,也就是说,同一个事件只能做一件事,这是因为 JavaScript 这门脚本语言诞生的使命所致 ——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的,比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行,应该先进行添加,之后再删除
# 同步和异步
为了解决这个问题,利用多喝 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,于是 JS 中出现了同步和异步
同步 前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的,同步的
异步 在做一件事时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情

同步任务
- 都在主线程上执行,形成一个执行栈
异步任务
JS 的异步任务通过回调函数实现
一般而言,异步任务有以下三种类型
- 普通事件,如
click,resize等 - 资源加载,如
load,error等 - 定时器,包括
setTimeout,setInterval等
异步任务相关回调函数添加到任务队列中 (任务队列也成为消息队列)
# JS 执行顺序
- 限制性执行栈中的同步任务
- 异步任务 (回调函数) 放入任务队列中
- 一旦执行栈的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
由于主线程不断地重复获取任务,执行任务,再获取任务,再执行,所以这种机制被称为事件循环 (event loop)
# location 对象
window 对象提供了一个 location 属性用于获取或设置窗体的 URL, 并且可以用于解析 URL, 因为这个属性返回的是一个对象,所以我们将这个属性也称为 location 对象
统一资源定位符 (Uniform Resource Locator, URL) 是互联网上标准资源的地址,互联网上的每个文件都有一个唯一的的 URL, 它包含的信息指出文件的位置以及浏览器应该怎么处理它
URL 一般的语法格式为 :
protocol://host[:port]/path/[?query]#fragment
组成 说明 protocol 通信协议 常用的 http, https, maito 等 host 主机 (域名) www.baidu.com port 端口号 可选,省略是使用方案默认的窗口,如 http 默认窗口为 80 path 路径 由 零或多个 '/' 字符隔开的字符串,一般用来表示主机上的一个目录或者文件地址 query 参数 以键值对的形式,通过 & 符号分隔开来 fragment 片段 #后面内容 常见于链接
# location 对象的属性
| location 对象属性 | 返回值 |
|---|---|
| location.href | 获取或者设置整个 URL |
| location.host | 返回主机 (域名) |
| location.port | 返回端口号,如果未写返回空字符串 |
| location.pathname | 返回路径 |
| location.search | 返回参数 |
| location.hash | 返回片段 #后面内容 常见于链接 锚点 |
重点记住 : href 和 search
# assign
重定向页面,浏览器可以保存重定向之前的页面,也就是说可以后退到上一个页面
1 | setTimeout(function () { |
# replace
重定向页面,浏览器不会保存浏览历史
1 | setTimeout(function () { |
# reload
重新加载页面,相当于刷新按钮或按 F5, 如果参数为 true, 强制刷新 CTRL + F5
1 | location.reload(); |
# navigator 对象
navigator 对象包含有关浏览器的信息,它由很多属性,我们最常用的是
userAgent, 该属性可以返回由客户机发送服务器的user-agent头部的值
# history 对象
window 对象提供了一个 history 对象,与浏览器历史记录进行交互,该对象包含用户 (在浏览器窗口中) 访问过的 URL
| history 对象方法 | 作用 |
|---|---|
| back() | 可以后退功能 |
| forward() | 前进功能 |
| go (参数) | 前进后退功能,参数如果是 1, 前进一个页面,如果是 - 1, 后退一个页面 |
1 | var btns = document.querySelectorAll('button'); |
# 网页特效
# offsetLeft 和 offsetTop 获取元素偏移量
offset 翻译过来就是偏移量,使用 offset 系列相关属性可以动态的得到该元素的位置 (品阿姨), 大小等
- 获得元素距离带有定位父元素的位置
- 获得元素自身的大小 (宽度高度)
注意 : 返回的数值都不带单位
offset 系列常用属性 :
| offset 系列属性 | 作用 |
|---|---|
| element.offsetParent | 返回作为该元素带有定位的父级元素,如果父级没有定位则返回 body |
| element.offsetTop | 返回元素相对带有定位父元素上方的偏移 |
| element.offsetLeft | 返回元素相对带有定位父元素左边框的偏移 |
| element.offsetWidth | 返回子升包括 padding, 边框,内容区的宽度,返回数值不带单位 |
| element.offsetHeight | 返回自身包括 padding 边框,内容区的高度,返回数值不带单位 |
如果父元素的样式表中没有 position 属性说明位置的话,则默认显示子元素的绝对偏移量,如果父元素中有的话,则显示子元素相对于父元素的相对偏移量
1 | .father { |
offset 和 style 的区别
| offset | style |
|---|---|
| offset 可以得到任意样式表中的样式值 | style 只能得到行内样式表中的样式值 |
| offset 系列获得的数值是没有单位的 | style.width 获得的是由单位的字符串 |
| offsetWidth 包含 padding + border + width | style.width 获得不包含 padding 和 border 的值 |
| offsetWidth 等属性是只读属性,只能获取不能赋值 | style.width 是可读属性,可以获取也可以赋值 |
| 所以,如果想要获取元素大小位置,使用 offset 更佳合适 | 所以,如果想要给元素更改值,则需要 style 改变 |
# 获取鼠标在盒子内的坐标
1 | var father = document.querySelector('.father'); |
# 元素可视区 client 系列
client翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息,通过client系列的相关属性可以动态的得到元素的边框大小,元素大小等
| client 系列属性 | 作用 |
|---|---|
| element.clientTop | 返回元素上边框的大小 |
| element.clentLeft | 返回元素左边框的大小 |
| element.clientWidth | 返回自身包括 padding, 内容区的宽度,不含边框,返回数值不带单位 |
| element.clientHeight | 返回自身包括 padding, 内容区的高度,不含边框,返回数值不带单位 |
client翻译过来就是客户端。我们使用client系列的相关属性来获取元素可视区的相关信息,通过client系列的相关属性可以动态的得到该元素的边框大小,元素大小等
# 立即执行函数
立即执行函数:不需要调用,立马能够自己执行的函数
(function(){}())或(function(){})()
立即函数最大的作用就是:独立创建了一个作用域,里面所有的变量都是局部变量,不会有命名冲突的情况
# 淘宝 flexible.js 源码解析
以下三种情况都会刷新页面都会触发 load 事件
- a 标签的超链接
- F5 或者刷新按钮 (强制刷新)
- 前进后退按钮
但是在火狐中,有个 "往返缓存", 这个缓存中不仅保存着页面数据,还保存了 DOM 和 JavaScript 的状态,实际上是将整个页面都保存在了内存里
所以此时后退按钮不能刷新页面
此时可以使用 pageshow 事件来触发,这个事件在页面显示时触发,无论页面是否来自缓存,在重新加载页面中, pageshow 会在 load 事件触发后触发,根据事件对象中的 persisted 来判断是否缓存中的页面触发的 pageshow 事件,注意这个事件给 window 添加
persisted 属性是判断页面是否由缓存加载,是 为 true , 否 为 false
# scroll 系列书信
scroll翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小,滚动距离等
| scroll 系列属性 | 作用 |
|---|---|
| element.scrollTop | 返回被卷去的上侧距离,返回数值不带单位 |
| element.scrollLeft | 返回被卷去的左侧距离,返回数值不带单位 |
| element.scrollWidth | 返回自身实际的宽度,不含边框,返回数值不带单位 |
| element.scrollHeight | 返回自身实际的高度,不含边框,返回数值不带单位 |
# 动画效果
定时器一般放在类里面,便于管理和区分,在设置定时器之前,消除此类之前存在的定时器
1 | var move = function (obj, target) { |
# 缓动效果
缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来
思路 :
- 让盒子每次移动的距离慢慢变小,速度就会慢下来
- 核心算法 : (目标值 - 现在位置) / 10 为每次移动的距离步长
- 停止的条件:让当前盒子位置等于目标位置就停止定时器
1 | var move = function (obj, target) { |
# 本地存储
# window.sessionStorage
- 声明周期为关闭浏览器窗口
- 在同一个窗口 (页面) 下数据可以共享
- 以键值对形式储存使用
储存数据 :
sessionStorage.setItem(key, value)
获取数据 :
sessionStorage.getItem(key)
删除数据 :
sessionStorage.removeItem(key)
清空数据 :
sessionStorage.clear()
1 |
|
# window.localStorage
- 生命周期永久生效,除非手动删除,否则关闭页面也会存在
- 可以多窗口 (页面) 共享 (同一浏览器可以共享)
- 以键值对的形式存储使用
存储数据 :
localStorage.setItem(key, value)
获取数据 :
localStorage.getItem(key)
删除数据 :
localStorage.removeItem(key)
清空数据 :
localStorage.clear()
