BOM(Browser Object Model)浏览器对象模型,BOM 是使用 JavaScript 开发 Web 应用程序的核心。
1. window 对象
BOM 的核心是 window 对象,表示浏览器的实例。
window 对象在浏览器中有两重身份,一个是ES 中的 Global 对象,另一个就是浏览器窗口的 JavaScript 接口。
1.1 Global 作用域
由于 window 对象被复用为 ECMAScript 的 Global 对象
所以通过 var 声明的所有全局变量和函数都会变成 window 对象的属性和方法。
例如:
var age = 29;
var sayAge = () => alert(this.age);
alert(window.age); // 29
sayAge(); // 29
window.sayAge(); // 29
如果使用 let 或 const 替代 var,则不会添加给全局对象
let age = 29;
const sayAge = () => alert(this.age);
alert(window.age); // undefined
sayAge(); // undefined
window.sayAge(); // TypeError: window.sayAge is not a function
另外,可以在 window 对象上查询是否存在可能未声明的变量。
1.2 窗口关系
- top 对象始终指向最上层窗口,即浏览器窗口本身。
- parent 对象则始终指向当前窗口的父窗口。
如果当前窗口是最上层窗口,则 parent 等于 top(都等于 window) - self 对象是终极 window 属性,始终会指向 window。
1.3 窗口位置与像素比
screenLeft 和screenTop 属性
- 用于表示窗口相对于屏幕左侧和顶部的位置
- 返回值的单位是 CSS 像素。
moveTo()和 moveBy()方法
作用:可以移动窗口
- moveTo()接收要移动到的新位置的绝对坐标 x 和 y;
- moveBy()则接收相对当前位置在两个方向上移动的像素数。
像素比
举个例子,手机屏幕的物理分辨率可能是 1920×1080,但因为其像素可能非常小,所以浏览器就需
要将其分辨率降为较低的逻辑分辨率,比如 640×320。这个物理像素与 CSS 像素之间的转换比率由
window.devicePixelRatio 属性提供。
window.devicePixelRatio 实际上与每英寸像素数(DPI,dots per inch)是对应的。
1.4 窗口大小
4个属性:innerWidth、innerHeight、outerWidth 和 outerHeight
- innerWidth、innerHeight 返回浏览器窗口中页面视口的大小(不包含浏览器边框和工具栏)
- outerWidth 和 outerHeight 返回浏览器窗口自身的大小
- document.documentElement.clientWidth 和document.documentElement.clientHeight返回页面视口的宽度和高度。
确定页面视口的大小:
let pageWidth = window.innerWidth,
pageHeight = window.innerHeight;
if (typeof pageWidth != "number") {
if (document.compatMode == "CSS1Compat"){
pageWidth = document.documentElement.clientWidth;
pageHeight = document.documentElement.clientHeight;
} else {
pageWidth = document.body.clientWidth;
pageHeight = document.body.clientHeight;
}
}
调整窗口大小
可以使用resizeTo()和resizeBy()方法
// 缩放到 100×100
window.resizeTo(100, 100);
// 缩放到 200×150
window.resizeBy(100, 50);
// 缩放到 300×300
window.resizeTo(300, 300);
1.5 视口位置
scroll()、scrollTo()和 scrollBy()方法滚动页面
// 相对于当前视口向下滚动 100 像素
window.scrollBy(0, 100);
// 相对于当前视口向右滚动 40 像素
window.scrollBy(40, 0);
// 滚动到页面左上角
window.scrollTo(0, 0);
// 滚动到距离屏幕左边及顶边各 100 像素的位置
window.scrollTo(100, 100);
也可以接收一个ScrollToOptions字典,通过 behavior 属性告诉浏览器是否平滑滚动。
// 正常滚动
window.scrollTo({
left: 100,
top: 100,
behavior: 'auto'
});
// 平滑滚动
window.scrollTo({
left: 100,
top: 100,
behavior: 'smooth'
});
1.6 导航与打开新窗口
windo.open()接收4个参数
要加载的 URL、目标窗口、特性字符串和表示新窗口在浏览器历史记录中是否替代当前加载页
面的布尔值。
// 与<a href="http://www.wrox.com" target="topFrame"/>相同
window.open("http://www.wrox.com/", "topFrame");
1.6.1 弹出窗口
如果window.open()的第二个参数不是已有窗口,则会打开一个新窗口或标签页。
第三个参数,特性字符串是一个逗号分隔的设置字符串
window.open("http://www.wrox.com/",
"wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
- window.open()方法返回一个对新建窗口的引用。与window对象一样。
- close()方法可以关闭新打开的窗口。
- 把 opener 设置为 null 表示新打开的标签页不需要与打开它的标签页通信,因此可以在独立进程中运行
let wroxWin = window.open("http://www.wrox.com/",
"wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
wroxWin.opener = null;
1.6.2 弹窗屏蔽程序
window.open()返回null则弹窗被屏蔽
let wroxWin = window.open("http://www.wrox.com", "_blank");
if (wroxWin == null){
alert("The popup was blocked!");
}
1.7 定时器
1.7.1 setTimeout()方法
setTimeout()用于指定在一定时间后执行某些代码
两个参数
- 1.要执行的代码:可以是字符串包含的代码,也可以是一个函数。
- 2.执行回调函数前等待的时间(毫秒)
// 在 1 秒后显示警告框
setTimeout(() => alert("Hello world!"), 1000);
在指定时间到达之前调用clearTimeout(),可以取消超时任务
// 设置超时任务
let timeoutId = setTimeout(() => alert("Hello world!"), 1000);
// 取消超时任务
clearTimeout(timeoutId);
setInterval()方法
setInterval()用于指定每隔一段时间执行某些代码。
和setTimeout()方法同样是接收两个参数
注意:这两个函数都不关心代码什么时候执行,只关心代码什么时候加入执行队列,当队列排到这个代码时才会执行。
取消定时,clearInterval()方法
let num = 0, intervalId = null;
let max = 10;
let incrementNumber = function() {
num++;
// 如果达到最大值,则取消所有未执行的任务
if (num == max) {
clearInterval(intervalId);
alert("Done");
}
}
intervalId = setInterval(incrementNumber, 500);
在实际开发中推荐用setTimeout()实现,因为一个任务结束和下一个任务开始之间的时间间隔是无法保证的。可以改成下面代码:
let num = 0;
let max = 10;
let incrementNumber = function() {
num++;
// 如果还没有达到最大值,再设置一个超时任务
if (num < max) {
setTimeout(incrementNumber, 500);
} else {
alert("Done");
}
}
setTimeout(incrementNumber, 500);
系统对话框
alert()、confirm()和 prompt()方法,调用系统对话框向用户显示消息
- 警告框(alert)通常用于向用户显示一些他们无法控制的消息
- 确认框confirm(),确认框有两个按钮:“Cancel”(取消)和“OK”(确定)
if (confirm("Are you sure?")) {
alert("I'm so glad you're sure!");
} else {
alert("I'm sorry to hear you're not sure.");
}
- 提示框prompt()
let result = prompt("What is your name? ", "");
if (result !== null) {
alert("Welcome, " + result);
}
2. location 对象
location提供了当前窗口中加载文档的信息,以及通常的导航功能
既是 window 的属性,也是 document 的属性.
2.1 查询字符串
URL 中的查询字符串并不容易使用,手动操作代码:
let getQueryStringArgs = function() {
// 取得没有开头问号的查询字符串
let qs = (location.search.length > 0 ? location.search.substring(1) : ""),
// 保存数据的对象
args = {};
// 把每个参数添加到 args 对象
for (let item of qs.split("&").map(kv => kv.split("="))) {
let name = decodeURIComponent(item[0]),
value = decodeURIComponent(item[1]);
if (name.length) {
args[name] = value;
}
}
return args;
}
现在,URLSearchParams 提供了一组标准 API 方法
给URLSearchParams 构造函数传入一个查询字符串,就可以创建一个实例。这个实例上暴露了 get()、set()和 delete()等方法
let qs = "?q=javascript&num=10";
let searchParams = new URLSearchParams(qs);
alert(searchParams.toString()); // " q=javascript&num=10"
searchParams.has("num"); // true
searchParams.get("num"); // 10
searchParams.set("page", "3");
alert(searchParams.toString()); // " q=javascript&num=10&page=3"
searchParams.delete("q");
alert(searchParams.toString()); // " num=10&page=3"
2.2 操作地址
assign()方法并传入一个 URL
location.assign("http://www.wrox.com");
给location.href 或 window.location 设置一个 URL,都会执行与显式调用 assign()一样的操作:
window.location = "http://www.wrox.com";
location.href = "http://www.wrox.com";
hash、search、hostname、pathname和 port 属性被设置为新值之后都会修改当前 URL,
2.2.1 replace()方法
调用 replace()之后,用户不能回到前一页
“后退”按钮是禁用状态
3. navigator 对象
navigator 对象的属性通常用于确定浏览器的类型。
用处好像不大,暂且放一放
4.history 对象
4.1 导航
// 后退一页
history.go(-1);
// 前进一页
history.go(1);
// 前进两页
history.go(2);
// 导航到最近的 wrox.com 页面
history.go("wrox.com");
// 导航到最近的 nczonline.net 页面
history.go("nczonline.net");
// 后退一页
history.back();
// 前进一页
history.forward();