BOM
window对象
window对象在浏览器中有两重身份,一是Global对象,而是浏览器窗口的js接口。网页中定义的所有对象,变量都可以以window作为Global对象,并且使用parseInt()等方法。
使用var会自动添加到全局对象中。而使用let则不会。window对象还可以用来查询是否存在未声明的变量
var temp = 1;  | 
窗口操作函数
window.self始终指向window本身,window.top始终指向浏览器窗口本身,而window.parent始终指向当前窗口的父窗口,如果本身就是最上层窗口,那么window.parent和window.top相同
- window.moveTo(x, y): 将左上角移动到对应位置
 - window.moveBy(dx, dy): 从当前位置移动若干像素
 
窗口大小
现代浏览器都支持四个属性:innerWidth/innerHeight/outerWidth/outerHeight.其中outerWidth和outerHeight返回浏览器自身窗口大小,而innerWidth和innerHeight返回浏览器可见视口大小(不包括边框和工具栏).
布局视口是整个页面的大小,有时候我们放大一下可能某些部分看不到了,可见视口就是可以看到的那一部分,布局视口包括看不到的部分。布局视口可以用document.body.clientWidth和document.body.clientHeight来获得。
- window.resizeTo(x, y): 缩放到某一个大小
 - window.resizeBy(x, y): 增加或减少一部分大小
 
例如:window.resizeTo(100, 100);//缩放到(100, 100)
window.resizeBy(100, 50);//缩放到(200, 150),增加了(100, 50)
- window.scrollBy(x, y, behavior): 向右滚动x像素,向下滚动y像素.behavior可以设置为smooth平滑滚动。
 - window.scrollTo(x, y, behavior): …
 
导航和新窗口
window.open(url, name, attribute): 弹出新窗口。如果名字是当前存在的窗口名,那么会跳转到对应窗口,否则会打开一个新窗口。特性字符串用来指定新窗口的一些设置,它使用逗号分隔,常见的设置有:
| 设置 | 说明 |
|-|-|
| fullscreen | 窗口是否最大化,只有IE支持 |
| height | 新窗口的高度, 不能小于100 |
| left | 新窗口x坐标 ,不能是负值 |
| top | 新窗口y坐标 |
| width | 新窗口宽度 |
| location | 是否显示地址栏,它还受浏览器影响 |
| Menubar | 是否显示菜单栏,默认为”no” |
| resizable | 是否可以更改大小, 默认为”no” |
| scrollbars | 是否可以滚动,默认为”no” |
| status | 是否显示状态栏,受浏览器影响 |
| toolbar | 是否显示工具栏,默认为”no” |例如:
window.open("http://www.wrox.com/",
"wroxWindow",
"height=400, width=400, resizable=yes");- window.close(): 关闭窗口。不能使用这个函数关闭主窗口,但是可以关闭弹出窗口。
 
新窗口有一个opener指向打开自己的window对象,例如:let win = window.open("http://www.wrox.com/", "wroxwindow");
alert(win === window);//true
由于过去弹窗被广告滥用了,因此现在对弹窗增加了许多限制。例如在网页加载过程中使用window.open()没有效果,只有在用户操作下才允许创建弹窗。
如果弹窗被屏蔽了,那么他会返回null,并且有的还会让它抛出错误,因此除了检测返回值,还需要使用try/catchlet blocked = false;
try
{
    let win = window.open("http://www.wrox.com", "_blank");
    if(win == null)
    {
        blocked = true;
    }
}
catch(ex)
{
    alert("blocked");
}
定时器
- setTimeout(func, time, arguments):func是要执行的函数,time是等待的时间。并不是说需要等待这么久就可以执行,而是等待这么久才有执行的机会。arguments是要传入函数的参数
 
js内部维护了一个消息队列,第二个参数的含义是等待time时间之后才把这个函数放入消息队列中。在时间结束前调用clearTimeout()可以取消任务,例如
let timeout = setTimeout(()=>alert("hello world"), 1000);  | 
- setInterval(…): setInterval和setTimeout类似,只是它是循环计时的
 - clearInterval(): …
 
对话框
- alert(message): 传递一个警示对话框,只有一个ok按钮

 - confirm(): 有两个按钮,ok和cancel,返回true为ok
 - prompt(): 提示用户输入消息,两个参数分别是提示文字和输入框内的默认值。点击ok会返回文本框内的值,点击cancel会返回null
 - print(): 打印对话框
 
location对象
location记载了一些窗口的属性并且提供url操作方法。可以使用window.location或document.location进行访问
以http://foouser.barpassword@www.wrox.com:80/WileyCDA/?q=javascript#contents来说明
| 属性 | 说明 | 
|---|---|
| location.hash | url的散列值(也就是#contents) | 
| location.host | 服务器名和端口号 | 
| location.hostname | 服务器名(www.wrox.com) | 
| href | 完整url | 
| pathname | 路径和文件名,上面例子中是/WileyCDA/ | 
| port | 端口 | 
| protocol | 协议类型,一般是http: 或https: | 
| search | 查询字符串,以问号开头. ?q=javascript | 
| username | 用户名 | 
| password | 密码 | 
| origin | url源地址,只读。http://www.wrox.com | 
查询参数分割
location.search返回的是一整个字符串,里面可能有很多个查询项,获得所有单个查询项的方法为:let getQueryString = function()
{
    let q = (location.search.length > 0) ? location.search.substring(1):"";
    args = {};
    
    //第一个split分割出每一个查询,第二个分割出问题和答案
    for(let item of q.split("&").map(kv => split("=")))
    {
        let name = decodeURIComponent(item[0]);//解码
        let value = decodeURIComponent(item[1]);
        if(name.length)
        {
            args[name] = value;
        }
    }
    return args;
}
此外,还可以使用URLSearchParams类,它提供了get(),set(),delete()等方法用来查询字符串let searchParams = new URLSearchParams(location.search);
searchParams.has("num");
searchParams.get("num");
...
for(let param of searchParams)//param是一个键值对
{
    ...
}
修改url
可以使用location.assign传入一个url。它会导航到一个新的url,并且会在历史记录中添加一条记录。设置location.href或window.location,也会调用assign()。对location的一些属性设置也有同样的效果
window.location = "http://www.wrox.com";  | 
如果不希望增加历史记录,可以使用replace方法,使用之后不能用撤回按钮恢复到原始页面。
- reload(from_server): 重新加载页面,from_server表示是否强制从服务器加载
 
navigator对象
navigator用来保存浏览器的一些属性
| 属性/方法 | 说明 | 
|---|---|
| activeVrDisplays | 返回数组,包含ispresenting属性为true的VRDisply实例(VR设置属性) | 
| appCodeName | 即使在非Mozilla浏览器中也会返回”Mozilla” | 
| appName | 浏览器全名 | 
| appVersion | 浏览器版本,通常和实际不一致 | 
| battery | 返回BatteryManager对象(电源管理) | 
| buildId | 浏览器构建编号 | 
| connection | NetworkInformation对象 | 
| cookieEnabled | 是否启用cookie | 
| credentials | 返回CredentialsContainer对象 | 
| deviceMemory | 返回以GB为单位的内存容量 | 
| doNotTrack | 返回用户”不跟踪”设置 | 
| geolocation | 返回Geolocation对象(地理位置定位) | 
| hardwareConcurrency | 设备处理器核心数量 | 
| javaEnabled | 是否启用java | 
| language | 浏览器主语言 | 
| languages | 偏好语言数组 | 
| locks | LockManager对象 | 
| mediaCapabilities | 返回MediaCapabilities对象 | 
| mediaDevices | 返回可用媒体数量 | 
| maxTouchPoints | 设备触摸屏最大触点数 | 
| mimeTypes | 返回浏览器注册的MIME类型数组(MIME是一种类型表述方法,可以说明它使文本还是音频、视频还是其他) | 
| onLine | 浏览器是否联网 | 
| oscpu | 返回操作系统和cpu型号 | 
| permissions | 返回Permissions对象 | 
| plugins | 插件数组 | 
| … | 
检测插件
插件数组中的每一项都包含下列属性:
- name: 插件名称
 - description: 插件介绍
 - filename: 插件文件名
 - length: 插件处理的MIME类型数量
 
注册处理程序
可以使用navigator.registerProtocolHandler()方法注册为某些特定信息的处理程序,就像操作系统上的默认应用一样。
- registerProtocolHandler(protocol, url, name): protocol是要处理的协议类型(如mailto或ftp),url是处理该协议的url,name是应用名称。例如:
 
navigator.registerProtocolHandler("mailto",  | 
screen和history
screen反映了屏幕的一些信息。可以从这里获得它的属性
history的go方法可以向任何方向导航,如果传入的参数是负数,表示后退若干页。反之为前进若干页。
go方法也可以是一个字符串,这种情况下会导航到包含字符串的第一个位置,这个位置可能是前进也可能是后退。history.go(-1);
history.go("wrox.com");
用户点击切换页面时会有一个haschange事件,我们可以在这时执行某些操作改变url而不打开新页面。可以使用history.pushState()
pushState(state, title, relativeurl): state是一个状态对象,这个对象保存有初始化页面状态所需要的信息,它的大小一般最大为500kb-1mb。第二个参数并未使用,第三个参数时要跳转的页面。
pushState执行后,当前状态会被推入历史记录中,地址栏也会变为新的url。但是即使location.href返回的是新内容,浏览器也不会向服务器发送请求。
- popState: 点击后退按钮会触发一个popState事件,这个事件中有一个state属性,它表示pushState()中的第一个参数
 - history.state: 表示当前状态对象
 - replaceState(state, name): 更新当前状态对象
 
``
history.pushState({foo: ‘bar’}, “title”, “baz.html”);
window.addEventListener(“popstate”, (event)=>{
    let state = event.state;
    if(state)
    {
        processState(state);
    }
});
history.replaceState({bar: ‘bar’}, “new title”);
```