# window对象
BOM 的核心是 window 对象,表示浏览器的实例。 window 对象在浏览器中有两重身份,一个是 ECMAScript 中的 Global 对象,另一个就是浏览器窗口的 JavaScript 接口。
# Global作用域
- 通过 var 声明的所有全局变量和函数都会变成 window 对象的属性和方法
- JavaScript 中有很多对象都暴露在全局作用域中
# 窗口关系
- top对象始终指向最上层(最外层)窗口,即浏览器窗口本身
- parent对象始终指向当前窗口的父窗口
- 如果当前窗口是最上层窗口,则parent等于top(都邓鼓window)
- self对象是终极window属性,始终指向window(self 和 window实际是同一个对象,之所以暴露self,是为了和top、parent保持一致)
# 窗口位置与象素比
- screenLeft和screenTop属性用于表示窗口相对于屏幕左侧和顶部的位置,返回值单位为CSS像素
- 可以使用moveTo()和moveBy()移动窗口(依浏览器而定,这俩方法部分或全部被禁用)
- moveTo()接收要移动到的新位置的绝对坐标x和y
- moveBy()接收相对当前位置在两个方向上移动的像素数
- 像素比
- window.devicePixelRatio与每英寸像素数(DPI,dots per inch)对应,DPI表示单位像素密度,window.devicePixelRatio表示物理像素与逻辑像素之间的缩放系数
# 窗口大小
- outerWidth和outerHeight返回浏览器窗口自身的大小
- innerWidth和innerHeight返回浏览器窗口中页面视口的大小(不含浏览器边框和工具栏)
- document.documentElement.clientHeight和document.documentElement.clientWidth返回页面视口的宽度和高度
- resizeTo()或resizeBy()可以调整窗口大小(可能被禁用)
- resizeTo()接收新的宽度和高度
- resizeBy()接收宽度和高度各要缩放多少
# 视口位置
- 度量文档相对于视口滚动距离的属性有两对,返回相等的值:window.pageXoffset/window.scrollX和window.pageYoffset/window.scrollY
- 可以使用scroll()、scrollTo()和scrollBy()方法滚动页面。三个方法都接收表示相对视口距离的x和y坐标,前两个表示要滚到的坐标,最后一个表示滚动的距离
- 这几个方法都接收一个ScrollToOptions对象,除了提供偏移值,还可以通过behavior属性告诉浏览器是否平滑滚动
# 导航与打开新窗口
window.open()可以用于导航到指定URL,也可以用于打开新浏览器窗口
- 接收四个参数:要加载的URL、目标窗口、特性字符串和表示新窗口在浏览器历史记录中是否代替当前加载页面的布尔值
弹出窗口
- window.open()的第二个参数不是已有窗口,则会打开一个新窗口或标签页
- 第三个参数即特性字符串,用于指定新窗口的配置
- 如果不指定这会带所有默认的浏览器特性
- 如果打开的不是新窗口,则忽略第三个参数
- window.open()返回一个对新建窗口的引用,可以以此控制新窗口
- 可以用close()关闭新打开的窗口
- 新建窗口的window对象有一个属性opener,指向打开它的窗口
- 窗口不会跟踪记录自己打开的新窗口,需要开发者自己管理
- 某些浏览器中,每个标签页会运行在独立进程中,如果一个标签打开了另一个,而window对象需要和另一个标签页通信,则新标签页不能运行在独立进程中(在这些浏览器中,将新开标签页的opener设置为null会使其运行与独立进程,这种连接一旦断开就无法恢复)
安全限制
弹出窗口被在线广告滥用,浏览器对此进行了一些限制
- 在用户操作西安才允许创建弹窗
- 网页加载过程中调用window.open()没有效果,还可能向用户显示错误
- 弹窗通常可能在鼠标点击或按下键盘中某个键的情况下才能打开
弹窗屏蔽程序
代码语言:javascript复制所有现代浏览器都内置了屏蔽弹窗的程序,因此大多数意料之外的弹窗都会被屏蔽
// 如果浏览器内置的弹窗屏蔽程序阻止了弹框,那window.open()可能返回null
// 通常也会抛出错误
// 可以以此来检测弹窗是否被屏蔽
let blocked = false;
try {
let wroxWin = window.open('http://www.baidu.com', '_blank');
if (wroxWin == null) {
blocked = true;
}
} catch(e) {
blocked = true;
}
if (blocked) {
alert('The popup was blocked!');
}
# 定时器
- setTimeout()用于指定一定时间后执行某些代码
- 接收两个参数:要执行的代码和在执行回调函数前等待的时间(毫秒)
- 调用 setTimeout()时,会返回一个表示该超时排期的数值 ID。这个超时 ID 是被排期执行代码的唯一标识符,可用于取消该任务(调用 clearTimeout()方法并传入超时 ID)
- setInterval()用于指定每隔一段时间执行某些代码
- 接收两个参数:要执行的代码(字符串或函数),以及把下一次执行定时代码的任务添加到队列要等待的时间(毫秒)
- 返回一个循环定时 ID,可以用于在未来某个时间点上取消循环定时。要取消循环定时,可以调用 clearInterval()并传入定时 ID
# 系统对话框
使用 alert()、 confirm()和 prompt()方法,可以让浏览器调用系统对话框向用户显示消息
- alert():接收一个要显示给用户的字符串(如果不是,会调用传入值的toString进行转换),对话框只有一个“OK”(确定)按钮
- confirm: 确认框有两个按钮:“Cancel”(取消)和“OK”(确定),用户通过单击不同的按钮表明希望接下来执行什么操作,根据confirm()方法的返回值判断点击项,true->OK、false->Cancel
- prompt():提示用户输入消息
- 接收两个参数:要显示给用户的文本,以及文本框的默认值
- 如果用户单击了 OK 按钮,则 prompt()会返回文本框中的值。如果用户单击了 Cancel 按钮,或者对话框被关闭,则 prompt()会返回 null
- find()和print():
- 这两种对话框都是异步显示的,即控制权会立即返回给脚本
- 显示查找对话框或打印对话框
# location对象
location 提供了当前窗口中加载文档的信息,以及通常的导航功能, 它既是window的属性,也是document的属性。不仅保存着当前加载文档的信息,也保存着把URL解析为离散片段后能够通过属性访问的信息。
如 http://foouser:barpassword@www.wrox.com:80/WileyCDA/?q=javascript#contents
属性 | 值 | 说明 |
---|---|---|
location.hash | #contents | URL散列值,如果没有则为空字符串 |
location.host | www.wrox.com:80 | 服务器名加端口号 |
location.hostname | www.wrox.com | 服务器名 |
location.href | https://www.wrox.com:80/WileyCDA/?q=javascript#contents | 当前加载页面的完整URL。location的toString()返回值 |
location.pathname | /WileyCDA/ | URL中的路径和(或)文件名 |
location.port | 80 | 请求的端口号,如果URL中没有端口,则返回空字符串 |
location.protocol | http: | 页面使用的协议,通常为http: 或 https: |
location.search | ?q=javascript | URL的查询字符串,该字符串以问号开头 |
location.username | foouser | 域名前指定的用户名 |
location.password | barpassword | 域名前指定的密码 |
location.origin | http://www.wrong.com | URL的源地址,只读 |
- 查询字符串
- 可以用URLSearchParams解析查询字符串
- 操作地址
- location.assign() 导航到新URL,并在浏览器历史记录中增加一条记录
- 给location.href或window.location设置一个URL,实际还是以同一个URL值调用assign()方法
- 常见的是设置location.href,除了hash外,设置location的一个属性就会导致页面重新加载新URL
- 如果不希望增加历史记录,可以使用replace()方法,重定向后后退按钮是禁用状态
- reload() 能重新加载的当前显示的页面。空参可能会从缓存加载,传参true可强制从服务器重新加载
- location.assign() 导航到新URL,并在浏览器历史记录中增加一条记录
# navigator对象
navigator 对象的属性通常用于确定浏览器的类型
检测插件
- 通过plugins数组来确定,数组中每一项都包含如下属性
- name:插件名称
- description:插件介绍
- filename:插件的文件名
- length:由当前插件处理的 MIME 类型数量
function hasPlugin = function(name) {
name = name.toLowerCase();
for (let plugin of window.navigator.plugins) {
if (plugin.name.toLowerCase().indexOf(name) > -1) {
return true;
}
}
}
alert(hasPlugin('Flash'));
注册处理程序
随着在线 RSS 阅读器和电子邮件客户端的流行,可以借助这个方法将 Web 应用程序注册为像桌面软件一样的默认应用程序。
- registerProtocolHandler()可以把一个网站注册为处理某种特定类型信息应用程序
- 必须传入 3 个参数:要处理的协议(如"mailto"或"ftp")、处理该协议的 URL,以及应用名称
// 为"mailto"协议注册了一个处理程序,这样邮件地址就可以通过指定的 Web 应用程序打开
navigator.registerProtocolHandler("mailto",
"http://www.somemailclient.com?cmd=%s",
"Some Mail Client");
# screen对象
保存的纯粹是客户端能力信息,也就是浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度
属性 | 说明 |
---|---|
availHeight | 屏幕像素高度减去系统组件高度(只读) |
availLeft | 没有被系统组件占用的屏幕的最左侧像素(只读) |
availTop | 没有被系统组件占用的屏幕的最顶端像素(只读) |
availWidth | 屏幕像素宽度减去系统组件宽度(只读) |
colorDepth | 表示屏幕颜色的位数:多数系统是32(只读) |
height | 屏幕像素高度 |
left | 当前屏幕左边的像素距离 |
pixelDepth | 屏幕的位深(只读) |
top | 当前屏幕顶端的像素距离 |
width | 屏幕像素宽度 |
orientation | 返回 Screen Orientation API 中屏幕的朝向 |
# history对象
history 对象表示当前窗口首次使用以来用户的导航历史记录
- history 对象还有一个 length 属性,表示历史记录中有多个条目
# 导航
- go() 可以在用户历史记录中沿任何方向导航,接收一个整数参数,正值表示前进负值表示后退
- go()有两个简写方法: back()和 forward()
# 历史状态管理
现代 Web 应用程序开发中最难的环节之一就是历史记录管理。
- hashchange 会在页面 URL 的散列变化时被触发,开发者可以在此时执行某些操作。
- 状态管理 API 则可以让开发者改变浏览器 URL 而不会加载新页面。
- history.pushState():接收 3 个参数:一个 state 对象、一个新状态的标题和一个(可选的)相对 URL
- pushState()方法执行后,状态信息就会被推到历史记录中,浏览器地址栏也会改变以反映新的相对 URL
- 即使 location.href 返回的是地址栏中的内容,浏览器页不会向服务器发送请求
- 第一个参数应该包含正确初始化页面状态所必需的信息。为防止滥用,这个状态的对象大小是有限制的,通常在 500KB~ 1MB 以内
- pushState()会创建新的历史记录,所以也会相应地启用“后退”按钮。此时单击“后退”按钮,就会触发 window 对象上的 popstate 事件
- popstate 事件的事件对象有一个 state 属性,其中包含通过 pushState()第一个参数传入的 state 对象
- 点击“后退”按钮直到返回最初页面时, event.state 会为 null
- 可以通过 history.state 获取当前的状态对象,也可以使用replaceState()并传入与pushState()同样的前两个参数来更新状态
- 更新状态不会创建新历史记录,只会覆盖当前状态
- 传给 pushState()和 replaceState()的 state 对象应该只包含可以被序列化的信息。因此,DOM 元素之类并不适合放到状态对象里保存
使用 HTML5 状态管理时,要确保通过 pushState()创建的每个“假” URL 背后都对应着服务器上一个真实的物理 URL。否则,单击“刷新”按钮会导致 404 错误。所有单页应用程序( SPA, Single Page Application)框架都必须通过服务器或客户端的某些配置解决这个问题。