本篇为 JavaScript 系列笔记第七篇,将陆续更新后续内容。参考:黑马程序员JavaScript核心教程,前端基础教程
系列笔记:
JavaScript(一)—— 初识JavaScript / 注释 / 输入输出语句 / 变量 / 数据类型
JavaScript(二)—— 运算符 / 流程控制 / 数组
JavaScript(三)—— 函数 / 作用域 / 预解析 / 对象
JavaScript(四)—— 内置对象 / 简单数据类型与复杂类型
JavaScript(五)—— Web APIs 简介 / JavaScript 必须掌握的 DOM 操作
JavaScript(六)—— DOM 事件高级
一、BOM 概述
-
BOM ( Browser Object Model ) 是指 浏览器对象模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。
-
BOM 由多个对象组成,其中代表浏览器窗口的 Window 对象是 BOM 的顶层对象,其他对象都是该对象的子对象。
-
由于 BOM 没有相关标准,每个浏览器都有其自己对 BOM 的实现方式。BOM 有窗口对象、导航对象等一些实际上已经默认的标准,但对于这些对象和其它一些对象,每个浏览器都定义了自己的属性和方式。
对比一下 DOM 和 BOM
- DOM
- 文档对象模型
- DOM 就是把「文档」当作一个「对象」来看待
- DOM 的顶级对象是 document
- DOM 主要学习的是操作页面元素
- DOM 是 W3C 标准规范
- BOM
- 浏览器对象模型
- BOM 就是把「浏览器」当作一个「对象」来看待
- BOM 的顶级对象是 window
- BOM 学习的是浏览器窗口交互的一些对象
- BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差
BOM 构成
window 对象是浏览器的顶级对象,它具有双重角色
- 它是 JavaScript 访问浏览器窗口的一个接口
- 它是一个全局对象,定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法
在调用的时候可以省略 window, 前面学习的对话框都属于 window 对象方法,如alert()
、prompt()
等
注意:window下有一个特殊属性 window.name
,声明变量时不要用 name
二、window 对象常见事件
- 窗口加载事件 —— 方式一
1. window.onload = function () {} 传统方式
2. window.addEventListener('load', function () {}) 方法监听注册方式
window.onload
是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本事件、CSS文件等)
- 有了
window.onload
就可以把 JavaScript 代码写到页面元素上方,甚至外部 window.onload
传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload
为准;但如果使用addEventListener
则没有限制
- 窗口加载事件 —— 方式二
document.addEventListener('DOMContentLoaded', function () {})
DOMContentLoaded
事件触发时,仅当 DOM 加载完成,不包括样式表、图片、flash 等
- IE9 以上才支持
- 当页面图片很多时,为避免交互事件过长影响用户体验,可使用此方法
- 调整窗口大小事件
1. window.onresize = function () {}
2. window.addEventListener('resize', function () {})
window.onresize
是调整大小加载事件,当触发时就调用处理函数
注意:
- 只要窗口大小发生像素变化,就触发这个事件
- 常利用这个事件完成响应式布局,
window.innerWidth
当前屏幕的宽度
三、定时器
- 定时方法一 ——
setTimeout()
window.setTimeout(调用函数, [延迟的毫秒数])
此方法用于设置一个定时器,该定时器再定时到期后执行调用函数
- window 可省略
- 也可以直接写函数名,或者采用字符串 `函数名()`(不推荐)
- 省略延时的毫秒数,默认是 0
- 因为定时器可能有很多,所以我们经常给定时器赋值一个标识符
setTimeout()
这个调用函数我们也称 回调函数 callback
- 案例: 3 秒后自动关闭的广告
<img src="images/ad.jpg" alt="" class="ad">
<script>
var ad = document.querySelector('.ad');
setTimeout(function () {
ad.style.display = 'none';
}, 3000);
</script>
- 停止
setTimeout()
定时器
window.clearTimeout(timeoutID)
此方法取消了先前通过调用 setTimeout()
建立的定时器
- window 可以省略
- 里面的参数就是定时器的标识符
- 定时方法二 ——
setInterval()
window.setInterval(回调函数, [间隔的毫秒数])
此方法按周期重复调用回调函数。
- 案例:倒计时
<div>
<span class="hour">-0</span> :
<span class="minute">-0</span> :
<span class="second">-0</span>
</div>
<script>
var hour = document.querySelector('.hour');
var minute = document.querySelector('.minute');
var second = document.querySelector('.second');
var inputTime = +new Date('2021-10-2 20:00:00');
// 先调用,防止刷新页面时出现空白信息
countDown();
// 计时器,周期调用
setInterval(countDown, 1000);
// 倒计时函数
function countDown() {
var nowTime = +new Date();
var times = (inputTime - nowTime) / 1000; // 倒计时总毫秒数
var h = parseInt(times / 60 / 60 % 24);
h = h < 10 ? '0' + h : h;
hour.innerHTML = h;
var m = parseInt(times / 60 % 60);
m = m < 10 ? '0' + m : m;
minute.innerHTML = m;
var s = parseInt(times % 60);
s = s < 10 ? '0' + s : s;
second.innerHTML = s;
}
</script>
- 停止
setInterval()
定时器
window.clearInterval(intervalID)
此方法取消了先前通过调用 setInterval()
建立的定时器
- window 可以省略
- 里面的参数就是定时器的标识符
注意:首先要定义全局变量 timer,其次要将其赋值为 null,否则为 undefined 容易引起问题
- 案例:发送短信
点击按钮后,该按钮 3 秒之内不能再次点击,防止重复发送
手机号码: <input type="number"> <button>发送</button>
<script>
var btn = document.querySelector('button');
var time = 3;
btn.addEventListener('click', function () {
this.disabled = true;
var timer = setInterval(function () {
if (time <= 0) {
clearInterval(timer);
btn.innerHTML = '发送';
btn.disabled = false;
time = 3;
} else {
btn.innerHTML = '剩余' + time + '秒';
time--;
}
}, 1000)
})
</script>
四、JavaScript 执行机制
- JS 是单线程
JavaScript 语言的一大特点就是 单线程,同一时间只能做一件事。但是,这样势必会引起一个问题:如果 JavaScript 执行的时间过长,就会造成页面的渲染不连贯,导致页面渲染加载阻塞的效果。
- 同步和异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,于是 JavaScript 出现了 同步 和 异步。
-
同步
前一个任务执行结束再执行后一个任务,程序的执行顺序与任务的排列顺序是一致、同步的
-
异步
多任务多线程,可以同时执行多个任务
- 同步任务和异步任务
- 同步任务:同步任务都在主线程上执行,形成一个 执行栈
- 异步任务:JS 的异步任务是通过回调函数实现的
一般而言,异步任务有以下三种类型:
- 普通事件,如
click
、resize
等 - 资源加载,如
load
、error
等 - 定时器,包括
serInterval
、setTimeout
等
异步任务相关的 回调函数 添加到 任务队列(消息队列)中
A Question
对此进行分析:
- 先执行 执行栈中的同步任务
- 遇到异步任务(回调函数)将其放入任务队列中
- 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取 任务队列 中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈开始被执行
- JS 执行机制
由于主线程不断地重复获取任务、执行任务、再获取新任务、再执行,所以这种机制称为 事件循环(event loop)
五、location 对象
location 对象存储了当前文档位置 URL 相关的信息,简单地说就是网页地址字符串。使用 window 对象的 location 属性可以访问。
- URL
统一资源定位器,它是 WWW 的统一资源定位标志,就是指网络地址
URL的一般语法格式为:[ ] 内为可选
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
- protocol(协议):指定使用的传输协议,最常用的是HTTP协议
- hostname(主机名):是指存放资源的服务器的域名系统(DNS) 主机名或 IP 地址
- port(端口号):http 的默认端口为 80
- path(路径):一般用来表示主机上的一个目录或文件地址
- parameters(参数):用于指定特殊参数的可选项
- query(查询):键值对形式,用于给动态网页传递参数
- fragment(信息片断):字符串,用于指定网络资源中的片段
- location 对象属性
http://www.123.cn:80/news/index.asp?id=123&name=location#top
location 对象定义了 8 个属性,其中 7 个属性可以获取当前 URL 的各部分信息,另一个属性 href
包含了完整的 URL 信息,详细说明如下表所示
重点:location.href 和 location.search
- 案例:5 秒后自动跳转页面
var div = document.querySelector('div');
var time = 5;
countDown(); // 避免空白页面
var timer = setInterval(countDown, 1000);
function countDown() {
if (time > 0)
div.innerHTML = '页面将在' + time-- + '秒后跳转';
else
location.href = 'http://www.mi.com';
}
- 案例:获取 URL 参数数据
实现数据可以在不同页面中的相互传递
- 提交表单采用 HTTP
GET
方法;表单数据会附加在 action 属性的 URL 中,并以 ’ ? ’ 作为分隔符
- 利用
search
获取 ’ ? ’ 及后面部分, 再利用字符串截取和分隔来获取andy
,有时也会用到uname
,因此获取去掉 ’ ? ’ 再获取
- location 对象常见方法
location.assign()
记录浏览历史,可以实现后退location.replace()
不记录浏览历史,不可以进行后退location.reload(true)
强制刷新,清除缓存
六、navigator 对象
Navigator 接口表示用户代理的状态和标识。 它允许脚本查询它和注册自己进行一些活动。
- 可实现页面在不同终端之间的跳转
- 常用:
NavigatorID.userAgent
,返回当前浏览器的用户代理,即由客户机发送服务器的 user-agent 头部的值
下面代码可以判断哪个终端打开页面,并实现页面跳转
if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|
BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|
Windows Phone)/i))) {
window.location.href = ""; // 手机
} else {
window.location.href = ""; // 电脑
}
七、history 对象
history 对象,用于与浏览器历史记录进行交互,该对象包含用户(在浏览器窗口中)访问过的 URL