JavaScript 浏览器对象模型(Browser Object Model,BOM)

217 阅读20分钟

浏览器对象模型( BOM ) 是一种特定于浏览器的约定,指的是Web 浏览器公开的所有对象。与 Document Object Model 同,没有实现标准,也没有严格的定义,因此浏览器供应商可以自由地以他们希望的任何方式实现 BOM。

一、window 对象

BOM 的核心是 window 对象,表示浏览器的示例。window 对象在浏览器中有两种身份:

  • ECMAScript 中的 Global 对象
  • 浏览器窗口的 JavaScript 接口

1.1 Global 作用域

JavaScript 在浏览器中的全局对象就是window对象。这意味着使用 var 全局声明的所有变量和函数都成为对象的属性和方法。

例如,下述代码中使用 var 定义的全局变量 a 可以当作 window 对象的属性被访问到。

var a = 'hello'

console.log(window.a) // hello

1.2 窗口大小 与 改变窗口大小

(1)浏览器视口(viewport)大小

  • Window.innerWidth: (只读)返浏览器窗口的视口(viewport)宽度(以像素为单位);如果垂直滚动条存在,则这个属性将包括它的宽度。
  • window.innerHeight:(只读)浏览器窗口的视口(viewport)高度(以像素为单位);如果有水平滚动条,也包括滚动条高度

(2)浏览器窗口大小

  • Window.outerWidth:(只读)获取浏览器窗口外部的宽度(单位:像素)。包括侧边栏(如果存在)、窗口镶边(window chrome)和调正窗口大小的边框(window resizing borders/handles)。
  • Window.outerHeight:(只读)整个浏览器窗口的高度(单位:像素),包括侧边栏(如果存在)、窗口镶边(window chrome)和窗口调正边框(window resizing borders/handles)。

(3)resizeTo()

动态调整窗口的大小。

语法

window.resizeTo(aWidth, aHeight)

参数

  • aWidth 是一个整数,表示新的 outerWidth(单位:像素)(包括滚动条、窗口边框等)。
  • aHeight 是一个整数,表示新的 outerHeight(单位:像素)(包括滚动条、标题栏、窗口边框等)。 如果设置的是负值,会被当作 0 处理。

(4)resizeBy()

调整窗口大小。

语法

window.resizeBy(xDelta, yDelta)

参数

  • xDelta (可为负值)为窗口水平方向变化的像素值
  • yDelta (可为负值)为窗口垂直方向变化的像素值。 简单来说就是执行如下操作:
  • outerWidth = outerWidth + xDelta
  • outerHeight = outerHeight + yDelta 但是如果outerWidthouterHeight 已经达到屏幕最大限制,则不会

1.3 窗口位置 与 移动窗口

(1)screenX / screenLeft

screenXscreenLeft 是一个只读属性,它返回浏览器左边界到操作系统桌面左边界的水平距离。

screenLeft 只是 Window.screenX  属性的别名,最初只被 IE 浏览器所支持。现在主流的浏览器都已支持该属性。

推荐使用screenLeft

(2)screenY / screenTop

screenYscreenTop 是一个只读属性,它返回返回浏览器顶部距离系统桌面顶部的垂直距离。

screenTop 是旧的 Window.screenY 属性的别名。 screenTop 最初仅在 IE 中支持,但由于受欢迎程度而在各处引入。

推荐使用screenTop

(3)moveTo()

将当前窗口移动到指定的坐标位置。

语法

window.moveTo(x, y)

参数

  • x 是要移动到的位置横坐标
  • 是要移动到的位置纵坐标

(4)moveBy()

根据指定的值,移动当前窗口。

语法

window.moveBy(deltaX, deltaY)

参数

  • deltaX 表示窗口在水平方向移动的像素值。
  • deltaY 表示窗口在垂直方向移动的像素值。

1.4 滚动距离 与 页面滚动

浏览器窗口尺寸通常无法满足完整显示整个页面,为此用户可以通过滚动在有限的视口中查看文档。滚动距离是文档相对于视口来测量的,换个说法就是视口当前在文档中的位置。

(1)scrollX / pageXOffset

scrollX / pageXOffset返回文档/页面水平方向滚动的像素值。

pageXOffset 是 scrollX 的别名

(2)scrollY / pageYOffset

scrollY / pageYOffset返回文档/页面垂直方向滚动的像素值。

pageYOffset 是 scrollY 的别名

(3)scrollTo()

滚动到文档中的某个坐标。

语法

window.scrollTo(x-coord,y-coord )

window.scrollTo(options)

参数

  • x-coord 是文档中的横轴坐标。
  • y-coord 是文档中的纵轴坐标。
  • options 是一个包含三个属性的对象:
    1. top 等同于  y-coord
    2. left 等同于  x-coord
    3. behavior 类型String,表示滚动行为,支持参数 smooth(平滑滚动),instant(瞬间滚动),默认值auto

(4)scrollBy()

在窗口中按指定的偏移量滚动文档。

语法

window.scrollBy(x-coord, y-coord);
window.scrollBy(options)

参数

  • X 是水平滚动的偏移量,单位:像素。
  • Y 是垂直滚动的偏移量,单位:像素。

正数坐标会朝页面的右下方滚动,负数坐标会滚向页面的左上方。

  • options 是一个包含三个属性的对象:
    1. top 等同于  y-coord
    2. left 等同于  x-coord
    3. behavior 表示滚动行为,支持参数:smooth (平滑滚动),instant (瞬间滚动),默认值 auto,效果等同于 instant

(5)scroll()

scrollTo() 方法操作和效果相同。

1.5 打开新窗口 和 关闭当前窗口

(1)open()

Window 接口的 open()  方法,是用指定的名称将指定的资源加载到浏览器上下文(窗口 window ,内嵌框架 iframe 或者标签 tab )。如果没有指定名称,则一个新的窗口会被打开并且指定的资源会被加载进这个窗口的浏览器上下文中。

语法

let windowObjectReference = window.open(strUrl, strWindowName, [strWindowFeatures]);

参数

  • strUrl 新窗口需要载入的url地址strUrl可以是web上的html页面也可以是图片文件或者其他任何浏览器支持的文件格式。如果strUrl 是一个空值,那么打开的窗口将会是带有默认工具栏的空白窗口(加载about:blank)。
  • strWindowName 新窗口的名称。该字符串可以用来作为超链接 <a> 或表单 <form> 元素的target属性值。字符串中不能含有空白字符。注意:strWindowName 并不是新窗口的标题。

如果已经存在以 strWindowName 为名称的窗口,则不再打开一个新窗口,而是把 strUrl 加载到这个窗口中。在这种情况下,方法的返回值是这个已经打开的窗口,并忽略参数 strWindowFeatures 。

strUrl设为空字符串时,可以在不改变窗口地址的情况下获得一个已经打开的同名窗口的引用。如果要在每次调用 window.open()时都打开一个新窗口,则要把参数 strWindowName 设置为 _blank

  • strWindowFeatures 可选参数。是一个字符串值,这个值列出了将要打开的窗口的一些特性(窗口功能和工具栏) 。 字符串中不能包含任何空白字符,特性之间用逗号分隔开。

如果名称是 strWindowName 的窗口不存在并且又没有提供 strWindowFeatures 参数(或者 strWindowFeatures 参数为空字符串),则子窗口以父窗口默认的工具栏渲染。

如果你使用了 strWindowFeatures 参数,那么只需要列出新窗口中启用的特性,其它的特性(除了titlebarclose)将被禁用或移除。

如果 strWindowFeatures 参数中没有定义窗口大小,则新窗口的尺寸跟最近渲染的窗口尺寸一样。

如果 strWindowFeatures 参数中没有定义窗口位置,则新窗口显示在最近渲染的窗口的坐标偏移22个像素

如果你定义了 strWindowFeatures 参数,那么没有在这个字符串中列出的特性会被禁用或移除 (除了 titlebar 和 close 默认设置为yes)

设置说明
width数值新窗口的宽度。这个值不能小于 100
height数值新窗口高度。这个值不能小于 100
left数值新窗口的 x 轴坐标。这个值不能是负值
top数值新窗口的 y 轴坐标。这个值不能是负值
fullscreen"yes" 或 "no"表示新窗口是否最大化。仅限 IE 支持
location"yes" 或 "no"表示是否显示地址栏。不同浏览器的默认值也不一样。在设置为"no"时,地址栏可能隐藏或禁用(取决于浏览器)
Menubar"yes" 或 "no"表示是否显示菜单栏。默认为"no"
toolbar"yes" 或 "no"表示是否显示工具栏。默认为"no"
status"yes" 或 "no"表示是否显示状态栏。不同浏览器的默认值也不一样
scrollbars"yes" 或 "no"表示是否可以在内容过长时滚动。默认为"no"
resizable"yes" 或 "no"表示是否可以拖动改变新窗口大小。默认为"no"

image.png

返回值

WindowObjectReference

打开的新窗口对象的引用。如果调用失败,返回值会是 null 。如果父子窗口满足“同源策略]”,你可以通过这个引用访问新窗口的属性或方法

(2)close()

Window.close()  方法关闭当前窗口或某个指定的窗口。

该方法只能由 Window.open()方法打开的窗口的 window 对象来调用。如果一个窗口不是由脚本打开的,那么,在调用该方法时,JavaScript 控制台会出现类似下面的错误:不能使用脚本关闭一个不是由脚本打开的窗口。 或 Scripts may not close windows that were not opened by script. 。

如下代码:

// 用于存储将要打开的窗口(的引用)的全局变量
var openedWindow;

function openWindow() {
  openedWindow = window.open('moreinfo.htm');
}
// 关闭由 window.open() 打开的窗口
function closeOpenedWindow() {
  openedWindow.close();
}


// 关闭当前窗口
function closeCurrentWindow() {
  window.close();
}

(3)opener

返回打开当前窗口的那个窗口的引用,例如:在window A中打开了window B,B.opener 返回 A.

如果当前窗口是由另一个窗口打开的, window.opener保留了那个窗口的引用. 如果当前窗口不是由其他窗口打开的, 则该属性返回 null.

(4)closed

此只读属性表示所引用的窗口是否关闭

  • true: 窗口已被关闭。
  • false: 窗口是打开的。

1.5 系统对话框

(1)警告对话框 —— alert()

Window.alert() 方法显示一个警告对话框,上面显示有指定的文本内容以及一个"确定"按钮

window.alert(message);

message 是要显示在对话框中的文本字符串,如果传入其他类型的值,会转换成字符串.

(2)确认对话框 —— confirm()

Window.confirm() 方法显示一个具有一个可选消息和**两个按钮(确定和取消)**的模态对话框 。

result = window.confirm(message);
  • message 是要在对话框中显示的可选字符串。
  • result 是一个布尔值,表示是选择确定还是取消 (true表示OK)。 例如:
if (window.confirm("Do you really want to leave?")) {
  window.open("exit.html", "Thanks for Visiting!");
}

(3)提示对话框 —— prompt()

Window.prompt() 方法显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字

result = window.prompt(text, value);
  • result 用来存储用户输入文字的字符串,或者是 null。
  • text 用来提示用户输入文字的字符串,如果没有任何提示内容,该参数可以省略不写。
  • value 文本输入框中的默认值,该参数也可以省略不写。不过在 Internet Explorer 7 和 8 中,省略该参数会导致输入框中显示默认值"undefined"。

(4)搜索框 —— find()

在一个页面中搜索指定的字符串.

window.find(aString, aCaseSensitive, aBackwards, aWrapAround,
            aWholeWord, aSearchInFrames, aShowDialog);
  • aString:将要搜索的字符串
  • aCaseSensitive:布尔值,如果为true,表示搜索是区分大小写的.
  • aBackwards:布尔值.如果为true, 表示搜索方向为向上搜索.
  • aWrapAround:布尔值.如果为true, 表示为循环搜索.
  • aWholeWord:未实现 布尔值.如果为true,表示采用全字匹配搜索.该参数无效;
  • aSearchInFrames:布尔值.如果为true, 表示会搜索框架内的文本.
  • aShowDialog:布尔值.如果为true, 则会弹出一个搜索对话框.

返回值:如果搜索到指定的字符串,则返回 true,否则返回 false

(5)打印框 —— print

打开打印对话框打印当前文档.

二、Location 对象

window.location 只读属性,返回一个 Location 对象,其中包含有关文档当前位置的信息。

2.1 Location 对象的属性

(1)location.href

Location 接口的 href 属性是一个字符串化转换器(stringifier), 返回一个包含了完整 URL 的 USVString 值, 且允许 href 的更新.

string = object.href;
object.href = string;

尽管 window.location 是一个只读 Location 对象,但仍然可以赋给它一个 DOMString。这意味着您可以在大多数情况下处理 location,就像它是一个字符串一样:window.location = 'www.example.com',是 window.location.href = 'www.example.com'的同义词

(2)location.protocol

Location 接口的 protocol 属性是一个字符串,表示 URL 的协议方案,包括最后的 ':'

string = object.protocol;
object.protocol = string;

(3)location.host

Location 接口的 host 属性是包含了主机的一段 USVString,其中包含:主机名,如果 URL 的端口号是非空的,还会跟上一个 ':' ,最后是 URL 的端口号。

string = object.host;
object.host = string;

简单来说:host = hostname + : + port

(4)location.hostname

Location的 hostname 属性是包含了域名的一段 USVString

string = object.hostname;
object. hostname = string;

(5)location.port

Location 接口的 port 属性是一个包含 URL 端口号的字符串。如果 URL 不包含明确的端口号,它将被设置为 ''

string = object.port;
object.port = string;

(6)location.pathname

Location 接口的 pathname 属性是一个字符串,其中包含该位置的 URL 的路径,如果没有路径,它将是空字符串。

string = object.pathname;
object.pathname = string;

(7)location.search

Location 接口的 search 属性会返回一段 USVString,其中包含一个URL标识中的 '?JavaScript' 以及跟随其后的一串URL查询参数。

string = object.search;
object.search = string;

(8)location.hash

Location 接口的 hash 属性返回一个 USVString,其中会包含URL标识中的 '#' 和 后面URL片段标识符。

这里 fragment 不会经过百分比编码(URL编码)。如果 URL 中没有 fragment,该属性会包含一个空字符串,""

string = object.hash;
object.hash = string;

(9)location.origin

Location 接口的 origin 只读属性是一个字符串,其中包含所表示 URL 的来源的 Unicode 序列化

string = object.origin;

image.png

2.2 Location 对象的方法

(1)location.assign()

Location.assign()  方法会触发窗口加载并显示指定的URL的内容

如果由于安全原因无法执行跳转,那么会抛出一个 SECURITY_ERROR 类型的 DOMException。当调用此方法的脚本来源和页面的 Location 对象中定义的来源隶属于不同域的时候,就会抛出上述错误。

如果传入了一个无效的 URL,则会抛出一个 SYNTAX_ERROR 类型的 DOMException

location.assign(url);

(2)location.reload()

location.reload()  方法用来刷新当前页面,就像刷新按钮一样。

该方法在跨域调用(执行该方法的脚本文件的域和 Location 对象所在页面的域不同)时,将会抛出 SECURITY_ERROR DOMException 异常。

location.reload();

(3)location.replace()

Location.replace() 方法以给定的URL来替换当前的资源。 与assign() 方法 不同的是,调用 replace() 方法后,当前页面不会保存到会话历史中(session History),这样,用户点击回退按钮时,将不会再跳转到该页面。

因违反安全规则导致的赋值失败,浏览器将会抛出类型为 SECURITY_ERROR 的 DOMException 异常。当调用该方法的脚本所属的源与拥有 Location 对象所属源不同时,通常情况会发生这种异常,此时通常该脚本是存在不同的域下。

object.replace(url);

(4)location.toString()

toString() Location接口的 stringifier 方法返回包含整个URL的USVString}。它是Location.href的只读版本。

三、Navigator 对象

只读属性 Window.navigator 会返回一个 Navigator 对象的引用,可以用于请求运行当前代码的应用程序的相关信息

该对象相关信息可参考:MDN Navigator

四、Screen 对象

Window.screen 返回当前window的screen对象。screen对象实现了 Screen 接口,它是个特殊的对象,返回当前渲染窗口中和屏幕有关的属性

属性描述
availTop(只读)浏览器窗口在屏幕上的可占用空间上边距离屏幕上边界的像素值。
availLeft(只读)浏览器窗口在屏幕上的可占用空间左边距离屏幕左边界的像素值。
availHeight(只读)返回浏览器窗口在屏幕上可占用垂直空间,即最大高度。(屏幕高度减去系统组件的高度)
avaiWidth(只读)返回浏览器窗口在屏幕上可占用水平空间,即最大宽度。(屏幕宽度减去系统组件的宽度)
height返回屏幕的高度。
width返回屏幕的宽度。
colorDepth(只读)返回屏幕的颜色深度(color depth)。根据CSSOM( CSS对象模型 )视图,为兼容起见,该值总为24。。
pixelDepth(只读)返回屏幕的位深度/色彩深度(bit depth)。根据CSSOM( CSS对象模型 )视图,为兼容起见,该值总为24。
orientation(只读)返回屏幕当前的方向

五、History 对象

Window.history 一个只读属性,用来获取History 对象的引用,History 对象提供了操作浏览器会话历史(浏览器地址栏中访问的页面,以及当前页面中通过框架加载的页面)的接口。

5.1 History 对象的属性

(1)hstory.length

History.length是一个只读属性,返回当前session中的history个数,包含当前页面在内。举个例子,对于新开一个tab加载的页面当前属性返回值1。

(2)history.scrollRestoration

滚动恢复属性 允许web应用程序在历史导航上显式地设置默认滚动恢复行为

const scrollRestore = history.scrollRestoration
  • auto:将恢复用户已滚动到的页面上的位置。
  • manual:未还原页上的位置。用户必须手动滚动到该位置。

(3)history.state

返回在 history 栈顶的 任意 值的拷贝。 通过这种方式可以查看 state 值,不必等待 popstate事件发生后再查看。

5.2 History 对象的方法

(1)history.back()

在浏览器历史记录里前往上一页, 用户可点击浏览器左上角的 返回(←) 按钮模拟此方法. 等价于 history.go(-1).

当浏览器会话历史记录处于第一页时调用此方法没有效果,而且也不会报错。

(2)history.forward()

在浏览器历史记录里前往下一页,用户可点击浏览器左上角的 前进(→) 按钮模拟此方法. 等价于 history.go(1)

当浏览器历史栈处于最顶端时( 当前页面处于最后一页时 )调用此方法没有效果也不报错。

(3)history.go()

go()方法从会话历史记录中加载特定页面。你可以使用它在历史记录中前后移动,具体取决于delta参数的值

window.history.go(delta);
  • delta (可选) 相对于当前页面你要去往历史页面的位置。负值表示向后移动,正值表示向前移动。因此,例如:history.go(2)向前移动两页,history.go(-2)则向后移动两页。如果未向该函数传参或delta相等于0,则该函数与调用location.reload()具有相同的效果。

(4)history.pushState()

history.pushState()  方法向当前浏览器会话的历史堆栈中添加一个状态(state)

history.pushState(state, title[, url])
  • state 状态对象是一个JavaScript对象,它与pushState()创建的新历史记录条目相关联。 每当用户导航到新状态时,都会触发popstate事件,并且该事件的状态属性包含历史记录条目的状态对象的副本。

状态对象可以是任何可以序列化的对象。

  • title 当前大多数浏览器都忽略此参数,尽管将来可能会使用它。 在此处传递空字符串应该可以防止将来对方法的更改。 或者,您可以为要移动的状态传递简短的标题。

  • url 可选 新历史记录条目的URL由此参数指定。 请注意,浏览器不会在调用pushState() 之后尝试加载此URL,但可能会稍后尝试加载URL,例如在用户重新启动浏览器之后。 新的URL不必是绝对的。 如果是相对的,则相对于当前URL进行解析。 新网址必须与当前网址相同 origin; 否则,pushState()将引发异常。 如果未指定此参数,则将其设置为文档的当前URL。

(5)history.replaceState()

replaceState()方法使用state objectstitle,和 URL 作为参数, 替换当前历史记录实体,如果你想更新当前的state对象或者当前历史实体的URL来响应用户的的动作的话这个方法将会非常有用。

pushState()replaceState() 的区别在于:

  • pushState() 是向历史堆栈添加 state
  • replaceState() 是替换历史堆栈栈顶的 state

popstate 事件

每当激活同一文档中不同的历史记录条目时,popstate 事件就会在对应的 window 对象上触发。如果当前处于激活状态的历史记录条目是由 history.pushState() 方法创建的或者是由 history.replaceState() 方法修改的,则 popstate 事件的 state 属性包含了这个历史记录条目的 state 对象的一个拷贝

六、定时器

6.1 setTimeout()

setTimeout() 方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。

var timeoutID = scope.setTimeout(function[ , delay, arg1, arg2, ...]);
var timeoutID = scope.setTimeout(function[, delay]);
var timeoutID = scope.setTimeout(code[, delay]);
  • functionfunction 是你想要在到期时间(delay毫秒)之后执行的回调函数
  • code: 这是一个可选语法,在delay毫秒之后编译和执行字符串 (不推荐的, 因为有安全风险)。
  • delay 可选:延迟的毫秒数 (一秒等于1000毫秒),函数的调用会在该延迟之后发生。如果省略该参数,delay取默认值0,意味着“马上”执行,或者尽快执行。不管是哪种情况,实际的延迟时间可能会比期待的(delay毫秒数) 值长

返回值: timeoutID是一个正整数,表示定时器的编号。这个值可以传递给clearTimeout()来取消该定时器。

6.2 setTimeInterval

setInterval()  方法重复调用一个函数或执行一个代码片段,在每次调用之间具有固定的时间间隔。

它返回一个 interval ID,该 ID 唯一地标识时间间隔,因此你可以稍后通过调用 clearInterval()来移除定时器。

var intervalID = setInterval(func, [delay, arg1, arg2, ...]);
var intervalID = setInterval(function[, delay]);
var intervalID = setInterval(code, [delay]);

某些情况下可以使用setTimeout()方法来实现setInterval()的功能:

(function loop(){
   setTimeout(function() {
      // Your logic here

      loop();
  }, delay);
})();

七、浏览器存储

7.1 Storage 对象

Storage 提供了访问特定域名下的会话存储或本地存储的功能。

(1)Storage 对象的属性

  • Storage.length:(只读)返回一个整数,表示存储在 Storage 对象中的数据项数量

(2)Storage 对象的方法

  • Storage.key(key):该方法接受一个数值 n 作为参数,并返回存储中的第 n 个键名
  • Storage.getItem(keyName):该方法接受一个键名作为参数,返回键名对应的
  • Storage.setItem(keyName, keyValue):该方法接受一个键名和值作为参数,将会把键值对添加到存储中,如果键名存在,则更新其对应的值。
  • Storage.removeItem(keyName):该方法接受一个键名作为参数,并把该键名从存储中删除
  • Storage.clear():调用该方法会清空存储中的所有键名。

另外,Storage 对象中的键值对总是以字符串的形式存储。 (需要注意, 和js对象相比, 键值对总是以字符串的形式存储意味着数值类型会自动转化为字符串类型).

7.2 localStorage

只读的localStorage 属性允许访问一个Document 源(origin)的对象 Storage;存储的数据将保存在浏览器会话中。localStorage 类似 sessionStorage,但其区别在于:存储在 localStorage 的数据可以长期保留;而当页面会话结束——也就是说,当页面被关闭时,存储在 sessionStorage 的数据会被清除 。

应注意,无论数据存储在 localStorage 还是 sessionStorage ,它们都特定于页面的协议。

7.3 sessionStorage

sessionStorage 属性允许你访问一个,对应当前源的 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。

  • 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
  • 在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文, 这点和 session cookies 的运行方式不同。
  • 打开多个相同的 URL 的 Tabs 页面,会创建各自的 sessionStorage
  • 关闭对应浏览器标签或窗口,会清除对应的 sessionStorage

本文到此就结束啦,主要是对《JavaScript高级程序设计(第四版)》以及MDN文档的一些摘抄。

主要参考 [1] 《JavaScript高级程序设计(第四版)》
[2] Window