1. BOM
BOM
:Browser Object Model
-> 专门操作浏览器窗口 / 软件的API
1.1. window: 2 个角色
- 代替
ES
中的global
充当全局作用域对象 - 封装所有
DOM
和BOM
的API
1.1.1 window 的功能
history
: 保存当前窗口打开后, 成功访问的URL
历史记录栈location
: 保存当前窗口正在打开的URL
对象document
: 封装页面内容和DOM API
的根对象navigator
: 保存浏览器的配置信息screen
: 保存客户端显示设备的信息event
: 定义事件对象
2. 打开和关闭窗口
- 打开一个新窗口:
window.open('url', name)
name
: 新窗口在内存中的名称- 浏览器规定: 相同
name
的窗口只能打开 1 个, 后打开的会覆盖先打开的 - 预定义值:
_self
: 用当前窗口的name
打开新窗口- 结果: 新窗口覆盖当前窗口
_blank
: 不指定name
属性, 让浏览器随机分配name
- 结果: 每个窗口的
name
都不一样 -> 可以打开多个窗口
- 结果: 每个窗口的
- 浏览器规定: 相同
- 打开一个超链接: 4 种
- 在当前窗口打开, 可后退:
HTML
:<a href="url" target="_self">超链接</a>
JS
:window.open('url', '_self')
- 在当前窗口打开, 不可后退:
- 当前窗口每打开一个新
URL
, 都会将新的URL
保存到window.history
中 - 如果新
URL
是追加进window.history
中, 则可后退 - 如果新
URL
将当前URL
替换掉, 则不可后退 JS
:window.location.replace('url')
- 当前窗口每打开一个新
- 在新窗口打开, 可打开多个:
HTML
:<a href="url" target="_blank">超链接</a>
JS
:window.open('url', '_blank')
- 在新窗口打开, 只能打开 1 个:
HTML
:<a href="url" target="自定义name">超链接</a>
JS
:window.open('url', '自定义name')
- 在当前窗口打开, 可后退:
3. 定时器: 2 种
3.1. 周期性定时器
3.1.1. 什么是
让程序每间隔一段时间反复执行一项任务
3.1.2. 何时
- 只要一项任务需要每间隔一段时间反复执行
3.1.3. 如何: 3 步
-
定义任务函数:
function taskFun() { ...... }
- 定义了定时器每次要执行的任务
-
启动定时器:
var timer = setInterval(taskFun, 间隔时间)
-
强调:
taskFun
是回调函数, 不用加()
-
timer
是定时器序号, 在内存中唯一标识一个定时器的整数 -
间隔时间为
ms
-
-
停止定时器:
clearInterval(timer)
timer
是要停止的定时器序号- 停止定时器的 2 种方式:
- 手动停止: 用户通过操作来停止定时器
- 自动停止: 在任务函数中判断临界值
- 只要达到临界值, 就自动停止定时器
- 问题: 停止定时器不会自动清除
timer
变量( 序号 ), 有可能会影响其他定时器- 解决: 凡是停止定时器, 就需要手动清除
timer
:timer = null
- 解决: 凡是停止定时器, 就需要手动清除
3.2. 一次性定时器
3.2.1. 什么是
程序先等待一段时间, 再自动执行一次任务
3.2.2. 何时
- 先等待一段时间再自动执行一次
- 自执行一次后, 自动停止
3.2.3. 如何: 3 步
- 定义任务函数:
function taskFn() { ...... }
- 启动定时器:
var timer = setTimeout(taskFn, 等待ms)
- 停止定时器:
clearTimeout(timer)
3.2.4. 原理
定时器回调函数的执行顺序在主程序之后
-
试题
var a = 10 function fun() { a = 100 } setTimeout(fun, 0) console.log(a) // 10
4. BOM 常用对象
4.1. history
保存当前窗口打开后成功访问过的
URL
的历史记录栈
history.go(n)
:history.go(0)
: 刷新history.go(-1)
: 后退history.go(1)
: 前进
4.2. location
保存当前窗口正在打开的
URL
对象
-
属性:
-
location.href
: 获取 / 设置完整的URL
-
location.protocol
: 协议 -
location.host
: 主机名- 包含: 主机名 + 端口号
-
location.hostnam
: 仅主机名 -
location.port
: 端口号 -
location.pathname
: 相对路径 -
location.hash
: 锚点地址 -
location.search
: 获取URL
? 后的查询字符串
-
-
方法:
location.assign('url')
: 在当前页面打开新的URL
- 其实相当于:
location.href = 'url'
- 其实相当于:
location.replace('url')
: 在当前窗口打开新的URL
, 替换history
中当前URL
, 实现禁止后退location.reload(false / true)
: 刷新
-
试题: 2 种刷新
- 默认刷新: 优先使用本地缓存中的文件 -> 除非文件比服务器上的旧, 才被迫下载新文件
F5
history.go(0)
location.reload()
- 强制刷新: 每次强制跳过浏览器本地缓存, 总是从服务器下载新文件
location.reload(true)
- 默认刷新: 优先使用本地缓存中的文件 -> 除非文件比服务器上的旧, 才被迫下载新文件
4.3. screen
保存客户端显示设备的信息
- 获取屏幕宽度
CSS
: 媒体查询JS
:screen.width
- 获取屏幕的高度:
screen.height
4.4. navigator
封装浏览器配置信息的对象
navigator.cookieEnabled
: 判断是否启用了cookie
navigator.plugins
: 封装所有插件的集合- 判断浏览器的名称和版本:
navigator.userAgent
: 保存浏览器内核, 名称, 版本号的字符串
4.5. 窗口大小与窗口位置
4.5.1. 窗口大小
- 完整窗口大小:
window.outerWidth
/window.outerHeight
- 完整显示区大小:
window.innerWidth
/window.innerHeight
4.5.2. 调整窗口大小
- 在打开窗口时, 就规定大小
var config = "left=?, top=?, width=?, height=?"
window.open('url', 'name', config)
- 打开窗口后在调整 -> 被禁用
window.resizeTo(width, height)
window.resizeBy(width增量, height增量)
4.5.3. 窗口位置
- 窗口距离屏幕上边的位置:
window.screenTop
/window.screenY
- 窗口距离屏幕左边的位置:
window.screenLeft
/window.screenX
4.5.4. 调整窗口位置
window.moveTo(left, top)
window.moveBy(left增量, top增量)
4.6. event
4.6.1. 什么是
用户手动触发的或浏览器自己触发的页面状态的改变
- 当事件发生时, 都可以执行事件处理函数来响应事件的操作
4.6.2. 绑定事件处理函数: 3 种
- 在
HTML
中绑定:<Any on事件名='js语句'></Any>
/<Any on事件名='js语句' />
- Ex:
<button onclick="fun()">按钮</button>
- 问题: 不符合内容和行为分离的原则, 不便于维护
- Ex:
- 在
JS
中绑定:on 事件名
:elem.on事件名 = function () { // this 指代 elem }
- 局限: 一个事件, 只能绑定一个处理函数
addEventListener
: 可一个事件同时绑定多个处理函数elem.addEventListener('事件名', fn)
- 还可以移出事件
elem.removeEventListener('事件名', 函数名)
- 绑定有名函数, 先在外声明函数, 再添加函数名, 移出时也必须用函数名
- 问题: 绑定时如果使用匿名函数, 移出时无法找到原函数
- 解决: 如果一个处理函数可能被移除, 就必须用有名函数
4.6.3. 事件模型 / 周期: 3 个阶段
- 捕获: 由外向内, 记录各级父元素上绑定的事件处理函数 -> 只记录, 不触发
- 目标触发: 优先触发目标元素上的事件处理函数
- 冒泡: 由内向外, 安捕获顺序的反向, 依次执行父元素上的事件处理函数
IE8
: 2 个阶段 -> 没有捕获阶段
4.6.4. 事件对象: e
-
什么是: 事件发生时, 自动创建的, 封装事件信息的对象
-
如何获得: 事件对象, 默认作为处理函数的第一个参数传入
-
事件处理函数(e) { // e: 自动获得事件处理对象 }
-
IE8
: 事件对象自动保存在全局变量event
中 -
兼容处理
function eventHandler(e) { e = e || window.event }
-
-
何时: 只要希望获得事件的数据, 或修改事件的默认行为时
- 包括:
- 取消冒泡:
e.stopPropagation()
- 利用冒泡:
- 问题: 浏览器通过遍历方式查找事件处理函数执行, 添加的事件监听越多, 遍历越慢, 网页响应速度越慢
- 优化: 尽量少的添加事件监听
- 如何:
- 如果多个平级子元素绑定相同事件时, 可在父元素仅添加一个事件监听, 所有子元素共用
- 问题:
- 如何获得目标元素:
e.target
- 可能目标元素不是想要的, 就要先鉴别目标元素, 再决定是否执行操作
- 如何获得目标元素:
- 问题:
- 如果一个父元素下的子元素, 需要动态生成, 并绑定事件, 则必须将事件绑定在父元素上; 动态添加的子元素才能自动使用父元素上的事件, 而不需要反复单独绑定
- 如果多个平级子元素绑定相同事件时, 可在父元素仅添加一个事件监听, 所有子元素共用
- 问题: 浏览器通过遍历方式查找事件处理函数执行, 添加的事件监听越多, 遍历越慢, 网页响应速度越慢
- 阻止默认行为:
e.preventDefault()
- 2 个典型应用:
- 阻止
a
元素作为按钮时, 自动添加#
锚点地址 - 表单验证未通过时, 阻止默认提交
- 阻止
- 2 个典型应用:
- 取消冒泡:
- 包括:
4.6.5. 事件坐标
- 相对于屏幕左上角:
e.screenX
/e.screenY
- 相对于文档显示区左上角:
e.clientX
/e.clientY
- 相对于当前元素左上角:
e.offsetX
/e.offsetY
4.6.6. 页面滚动
- 事件:
window.onscroll
- 获得页面滚动的位置:
document.body.scrollTop