导言
本文内容如下:
- 理解window对象
- 控制窗口, 框架和弹出窗口
- 利用location 对象中的页面信息
- 使用 navigator 对象了解浏览器
window对象
BOM的核心对象是 window ,它表示浏览器的一个实例。
全局作用域
由于 window 对象同时扮演着 ES 中 Global 对象的角色。
因此所有在全局作用域中声明的变量, 函数都会变成 window 对象的属性和方法。
当然,这里说的是 使用 var在全局作用域中声明变量。
抛开全局变量会成为 window对象的属性不谈,定义全局变量与在 window对象上直接定义属性还是有一点差别:
- 全局变量不能通过 delete 操作符删除, 而直接在window对象上定义的属性可以。
var age = 26;
window.color = 'red';
delete window.age; // 不能删除
delete window.color; // 可以删除
使用var 语句添加到 window的属性有一个名为[[Configurable]]的特性,这个特性的值被设置为false,因此这样定义的属性不可以通过delete操作符删除
导航和打开窗口
额,这个API好像不怎么用到呀,就简单看看吧
window.open('https://www.baidu.com','_blank')
location 对象
location 它提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能。
事实上,window.location 与 document.location 引用的是同一个对象。
location将 URL解析成独立的片段,让开发人员可以通过不同的属性访问这些片段:
属性名 | 例子 | 说明 |
---|---|---|
hash | "#contents" | 返回URL中的 hash值, 如果URL中不包含散列,则返回空字符串 |
host | "www.baidu.com:80" | 返回服务器名称和端口号(如果有) |
hostname | "www.baidu.com" | 返回不带端口号的服务器名称 |
href | "www.baidu.com" | 返回当前加载页面的完整的URL.而lacation.toString()也是 |
pathname | "/s" | 返回 URL中的目录和文件名 |
port | "8080" | 返回URL的指定的端口号。如果URL中不包含端口号,则返回空字符串 |
protocol | "http:" | 返回页面使用的协议。通常是http或https |
search | "q=javascript" | 返回URL的查询字符串。这个字符串以问号开头 |
查询字符串参数
let search = "?query=hello&period=2&ka=sel-scale-2";
function Parse(search) {
let obj = {};
let s = search.slice(1);
let s_arr = s.split('&');
s_arr.forEach((para) => {
let arr_para = para.split('=');
obj[arr_para.shift()] = arr_para.pop();
})
return obj;
let search_o = Parse(search);
console.log(search_o);
/**
{
query: 'hello',
period: '2',
ka: 'sel-scale-2'
}
/
}
URLSearchParams
额,貌似,js自己带了一个可以解析 location.search的 API
- has():返回一个布尔值,表示是否具有某个参数
- get():返回指定参数的第一个值
- getAll():返回一个数组,成员是指定参数的所有值
- set():设置指定参数
- delete():删除指定参数
- append():在查询字符串之中,追加一个键值对
- toString():返回整个查询字符串
var paramsString = 'q=URLUtils.searchParams&topic=api';
var searchParams = new URLSearchParams(paramsString);
searchParams.has('topic') // true
searchParams.get('topic') // "api"
searchParams.getAll('topic') // ["api"]
searchParams.get('foo') // null,注意Firefox返回空字符串
searchParams.set('foo', 2);
searchParams.get('foo') // 2
searchParams.append('topic', 'webdev');
searchParams.toString() // "q=URLUtils.searchParams&topic=api&foo=2&topic=webdev"
searchParams.append('foo', 3);
searchParams.getAll('foo') // [2, 3]
searchParams.delete('topic');
searchParams.toString() // "q=URLUtils.searchParams&foo=2&foo=3"
history 对象
history 对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。
因为 history是 window对象的属性,因此每个浏览器窗口,每个标签页乃至每个框架,都有自己的history对象与特定的window对象关联。
使用go()方法可以实现历史记录中跳转
// 后退一页
history.go(-1);
// 前进一页
history.go(1);
// 前进两页
history.go(2);
当然,也可以给 go()方法传递一个字符串参数
history.go('baidu.com')
另外,还可以使用 back()和forward()来替代go
// 后退一页
history.back()
// 前进一页
history.forward()
1.概述
window.history 属性指向 history 对象 , 它表示当前窗口的浏览历史
当前窗口一共访问3个网址
window.history.length // 3
// 后退到前一个网址
history.back()
// 等同于
history.go(-1)
2.方法
History.pushState()
History.pushState() 方法用于在历史中添加一条记录
window.history.pushState(state, title, url)
该方法接收三个参数:
- state: 一个添加记录状态的对象, 主要用于 popstate 事件
- title : 忽略
- url : 新的网址, 必须与当前页面处于同一域中。
假定当前网址是 example.com/1.html,使用pushState()方法在浏览记录(History 对象)中添加一个新记录。
var stateObj = {foo : 'bar'};
history.pushState(stateObj, 'page 2', '2.html');
总之,pushState()方法不会触发页面刷新,只是导致 History 对象发生变化,地址栏会有反应。
如果pushState()方法设置了一个跨域网址,则会报错。
History.replaceState()
History.replaceState()方法用来修改 History 对象的当前记录,其他都与pushState()方法一模一样。
popstate 事件
每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。
注意,仅仅调用pushState()方法或replaceState()方法 ,并不会触发该事件,只有用户点击浏览器倒退按钮和前进按钮,或者使用 JavaScript 调用History.back()、History.forward()、History.go()方法时才会触发。
vue 中 history原理
我们知道 vue 的路由模式有:
- hash路由
- history路由
而history路由的原理如下
class Routers {
constructor() {
this.routes = {};
// 在初始化时监听popstate事件
this._bindPopState();
}
// 初始化路由
init(path) {
history.replaceState({ path: path }, null, path);
this.routes[path] && this.routes[path]();
}
// 将路径和对应回调函数加入hashMap储存
route(path, callback) {
this.routes[path] = callback || function () { };
}
// 触发路由对应回调
go(path) {
history.pushState({ path: path }, null, path);
this.routes[path] && this.routes[path]();
}
// 监听popstate事件
_bindPopState() {
window.addEventListener('popstate', e => {
const path = e.state && e.state.path;
this.routes[path] && this.routes[path]();
});
}
}
let Route = new Routers();
Route.route('/hello', function () {
console.log('hello')
})
function change() {
Route.go('/hello')
}