BOM
BOM:浏览器对象模型
8.1 window对象
window
对象是BOM的核心对象,它表示浏览器的一个实例。在浏览器中,window对象具有双重角色,它既是JavaScript访问浏览器窗口的一个接口,又是ECMAScript规定的Global
对象。这意味着在网页中定义的任何一个对象、变量和函数,都以window
作为其Global
对象,因此有权访问parseInt()
方法。
全局作用域:任何在全局作用域中声明的变量、函数都是`window对象的属性和方法。示例:
var age = 22;
function sayAge() {
return this.age;
}
alert(window.age); //22
alert(window.sayAge()); //22
定义全局变量或者函数与直接在window
对象上添加属性或者方法的区别:定义在全局环境中的变量和函数不可被delete
删除,而直接在window
对象上添加属性或者方法可以用delete
操作符删除。示例:
var age = 22;
window.color = "red";
//在IE9以下的浏览器会报错,其他浏览器返回false
delete window.age;
//在IE9以下的浏览器会报错,其他浏览器返回true
delete window.color;
alert(window.age); //22
alert(window.color); //undifined
定义在全局环境中的属性,其Configurable
特性的值为false
,所以不可使用delete
操作符删除。IE8及更早版本遇到使用delete
删除window
的属性时,不管属性是如何创建的,都会抛出错误,以示警告。IE9及之后的版本修复了这个问题。
尝试访问未声明的变量会抛出错误,但是可以通过查询window
对象,可以知道某个可能未声明的变量是否存在。示例:
//抛出错误,因为oldValue未定义
var newValue = oldValue;
//不会抛出错误,因为这是一次属性查询
var newValue = window.oldValue;
alert(newValue); //undefined
windows mobile平台的IE浏览器不允许通过window.property=value;
的方式直接在window
对象上添加属性和方法,只能将变量和函数定义在全局环境中,依然会成为window
对象的属性和方法。
窗口关系及框架
如果页面中包含框架,则每个框架都有自己的window
对象,并且保存在frames
集合中。在frames
集合中,可以通过数值索引(从0开始,从左至右,从上至下)或者框架名称来访问相应的window
对象。每个window
对象都有一个name
属性,其中包含框架的名称。访问某个框架一般有六种方式:
window.frames[索引值];
window.frames[frame的name值];
top.frames[索引值];
top.frames[frame的name值];
frames[索引值];
frames[frame的name值];
与top
相对的另一个window对象是parent
。顾名思义,parent
始终指向当前框架的直接上层框架。在某些情况下,parent
有可能等于top
;但是在没有框架的情况下,parent
一定等于top
(此时它们都等于window
)。
与框架有关的最后一个属性是self
,它始终指向window
,引入它的目的只是为了与top
对象和parent
对象对应起来,不具有其他值,和window
对象可以互换使用。
以上所有的对象都是window
对象的属性,甚至可以连接起来用,例如:window.parent.parent.frames[0]
在使用框架的情况下,浏览器会存在多个Global
对象。在每个框架中定义的全局变量会自动成为框架中window
对象的属性。由于每个window
对象都包含原生类型的构造函数,因此每个框架都有自己的一套构造函数,这些构造函数一一对应但并不相等。例如top.Object
并不等于top.frames[0].Object
。这个问题主要是影响到对跨框架传递的对象使用instanceof
操作符。
窗口位置
screenLeft和screenTop属性(IE Safari Opera Chrome):分别表示窗口相对于屏幕左边和屏幕上边的位置。
screenX和screenY属性(Firefox Safari Chrome):分别表示窗口相对于屏幕左边和屏幕上边的位置。
注意:Opera虽然也支持screenX和screenY这两个属性,但是却和screenLeft和screenTop这两个属性是不一样的。所以在Opera浏览器中尽量不要使用screenX和screenY这两个属性。
加入如下的代码可以跨浏览器取得窗口左边和上边的位置:
var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;
首先通过二元操作符确定screenLeft和screenTop属性是否存在,如果存在则使用这两个属性,如果不存在则使用screenX和screenY这两个属性(Firefox)。
但是不同的浏览器对这四个属性的定义有比较大的不同,结果就是无法在跨浏览器的条件下取得窗口左边和上边的精确坐标值。
moveTo()
和moveBy()
方法:这两个方法都接收两个参数,其中moveTo()
接收的是新位置的x和新位置的y坐标,而moveBy()
接收的是在水平和垂直方向上移动的像素数。示例:
//将窗口移动到屏幕的左上角
window.moveTo(0, 0);
将窗口向下移动100px
window.moveBy(0, 100);
//将窗口移动到200,300
window.moveTo(200, 300);
//将窗口向左移动50px
window.moveBy(-50, 0);
但是需要注意的是,这两个方法又可能被浏览器禁用,我用Chrome和Firefox都不能运行正常,使用IE倒是可以。另外,这两个方法都不适用于框架frame
,只能对最外层的window
对象使用。
窗口大小
跨浏览器确定窗口大小不是一件简单的事,IE9+、Firefox、Safari、Opera和Chrome均为此提供了四个属性:innerWidth
、innerHeight
、outerWidth
、outerHeight
。遗憾的当前主流的五种浏览器对这四个属性的解释又不一样了(无奈)……,下面是通过这四个属性获取到页面窗口的大小:
var 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;
}
}
alert(pageWidth);
alert(pageHeight);
简单解释一下:首先获取window.innerWidth
和window.innerHeight
赋值给pageWidth和pageHeight。然后检查pageWidth中是否保存了一个类型为number的数值;如果不是number数值,则再次检查,如果当前页面的文档类型是标准模式,则使用document.documentElement.clientWidth
和document.documentElement.clientHeight
为pageWidth和pageHeight重新赋值;如果文档类型为混杂模式,则通过document.body.clientWidth
和document.body.clientHeight
为pageWidth和pageHeight重新赋值。之所以先确定文档类型的模式,是因为浏览器的兼容问题(主要是IE6)。
补充:Chrome混杂模式下,使用document.documentElement
和document.body
获取clientWidth
和clientHeight
是一样的。
移动设备视口的话题更加复杂。
resizeTo()
和resizeBy()
方法:调整浏览器窗口的大小。类似于moveTo()
和moveBy()
方法,都接收两个参数。
relizeTo()
方法接收浏览器窗口的新高度和新宽度;relizeBy()
接收新窗口与原窗口的宽度和高度之差。
示例:
//调整到100*100
window.resizeTo(100, 100);
//调整到200*150
window.resizeBy(100, 50);
//调整到300*300
window.resizeTo(300, 300);
这两个方法也有可能被浏览器禁用,我用Firefox和Chrome都不能运行,应该是被禁用了,但是我又试了IE11,这次可以正常运行了。
同样,这两个方法不支持框架,只对最外层的window
对象有效。
导航和打开窗口
window.open()
方法:此方法接收四个参数:
- URL 一个可选的字符串,声明了要在新窗口中显示的文档的URL。如果省略了这个参数,或者它的值是空字符串,那么新窗口就不会显示任何文档。
- name 一个可选的字符串,该字符串是一个由逗号分隔的特征列表,其中包括数字、字母和下划线,该字符声明了新窗口的名称。这个名称可以用作标记
<a>
和<form>
的属性target
的值。如果该参数指定了一个已经存在的窗口,那么open()
方法就不再创建一个新窗口,而只是返回对指定窗口的引用。在这种情况下,features 将被忽略。- features 一个可选的字符串,声明了新窗口要显示的标准浏览器的特征。如果省略该参数,新窗口将具有所有标准特征。在窗口特征这个表格中,我们对该字符串的格式进行了详细的说明。
- replace 一个可选的布尔值。规定了装载到窗口的 URL。是在窗口的浏览历史中创建一个新条目,还是替换浏览历史中的当前条目。支持下面的值:
1. true - URL 替换浏览历史中的当前条目。
2. false - URL 在浏览历史中创建新的条目。
摘抄自W3SCHOOL
弹出窗口
窗口特征(Window Features)
- channelmode=yes|no|1|0 是否使用剧院模式显示窗口。默认为 no。
- directories=yes|no|1|0 是否添加目录按钮。默认为 yes。
- fullscreen=yes|no|1|0 是否使用全屏模式显示浏览器。默认是 no。处于全屏模式的窗口必须同时处于剧院模式。
- height=pixels 窗口文档显示区的高度。以像素计。
- left=pixels 窗口的 x 坐标。以像素计。
- location=yes|no|1|0 是否显示地址字段。默认是 yes。
- menubar=yes|no|1|0 是否显示菜单栏。默认是 yes。
- resizable=yes|no|1|0 窗口是否可调节尺寸。默认是 yes。
- scrollbars=yes|no|1|0 是否显示滚动条。默认是 yes。
- status=yes|no|1|0 是否添加状态栏。默认是 yes。
- titlebar=yes|no|1|0 是否显示标题栏。默认是 yes。
- toolbar=yes|no|1|0 是否显示浏览器的工具栏。默认是 yes。
- top=pixels 窗口的 y 坐标。
- width=pixels 窗口的文档显示区的宽度。以像素计。
摘抄自W3SCHOOL(JavaScript高设书中的那个表格貌似不准确,所以去w3school摘了一段)
使用示例:
window.open("http://www.baidu.com/", "newWindow", "height=400,width=400,top=10,left=10,resizable=yes");
这行代码可以打开一个新的可以调整大小的窗口,窗口初始大小为400*400px,并且距离屏幕上沿和左沿10px。
window.open()
方法返回一个指向新窗口的引用。引用的对象和其他window
对象大致相似,但可以进行更多的控制,例如:有些浏览器在默认情况下不允许针对主浏览器窗口大小进行调整或者移动位置,但是却允许我们针对通过window.open()
创建的窗口调整其大小和移动其位置。通过这个返回的对象,我们可以向操作其他窗口一样操作新打开的窗口,示例:
var newWindow = window.open("http://www.baidu.com/", "newWindow", "height=400,width=400,top=10,left=10,resizable=yes");
//调整其大小为800*500
newWindow.resizeTo(1000,500);
//移动其位置
newWindow.moveTo(100, 100);
调用close()
方法还可以关闭打开的窗口:
newWindow.close();
会看到窗口出现后立即自动关闭。
但是这些方法仅适用于通过window.open()
打开的弹出窗口,对于浏览器打开的主窗口,如果没有得到用户的允许是不能关闭它的。不过,弹出窗口可以调用top.close()在不经用户允许的情况下关闭自己,弹出窗口关闭以后,窗口的引用依然在,但是除了检查其closed
属性以外,没有其他作用了。示例:
newWindow.close();
alert(newWindow.closed); //true
新创建的window
对象有一个opener
属性,其中保存着打开它的原始窗口的对象。这个属性只在弹出窗口的最外层window
对象(top
)中有定义(弹出窗口也可能包含多个框架,有多个window
对象,然而这个属性只在top
中有定义),并且指向调用window.open()
的窗口或框架。示例:
var newWindow = window.open("http://www.baidu.com/", "newWindow", "height=400,width=400,top=10,left=10,resizable=yes");
alert(newWindow.opener === window); //true
虽然弹出窗口中有opener
属性,里面的指针指向打开它的原始窗口,但是原始窗口却没有这样一个指针指向它打开的弹出窗口。窗口并不跟踪记录它们打开的弹出窗口,因此我们只能在必要的时候自己来手动实现跟踪。
有些浏览器(如IE8和Chrome)会在独立的进程中运行每个标签页。当一个标签页打开另一个标签页时,如果两个window
对象的之间需要彼此通信,那么新标签页就不能运行在独立的进程当中。在Chrome中,将新创建的标签页的opener属性设置为null,即表示在单独的进程中运行新标签页,示例:
var newWindow = window.open("http://www.baidu.com/", "newWindow", "height=400,width=400,top=10,left=10,resizable=yes");
newWindow.opener = null;
将opener属性设置为null
就意味着告诉浏览器新创建的标签页不需要与打开它的标签页进行通信,因此可以在独立的进程中运行。标签页之间的联系一旦断开,就没有办法恢复了。
安全限制(为了针对肆无忌惮的广告商)
不同的浏览器有不同的策略,针对弹出窗口,有的屏蔽,有的根据用户操作来创建弹出窗口。
弹出窗口屏蔽程序
一般分为两种:浏览器内置弹出窗口屏蔽程序和浏览器扩展或其他应用程序的弹出窗口屏蔽程序。如果是浏览器内置弹出窗口屏蔽程序,那么window.open()
一般会返回null
,可以通过以下代码检测:
var newWindow = window.open("http://www.baidu.com/", "_blank");
if (newWindow == null) {
alert("The popup is locked!");
}
如果是浏览器扩展或其他应用程序的弹出窗口屏蔽程序,那么window.open()
一般会抛出一个错误。因此,如果想准确地检测出弹出窗口是否被屏蔽,必须在检测返回值的同时,将对window.open()
的调用封装在一个try……catch
块中:
var blocked = false;
try {
var newWindow = window.open("http://www.baidu.com/", "_blank");
if (newWindow == null) {
blocked = true;
}
} catch (ex) {
blocked = true;
};
if (blocked) {
alert("The popup is locked!");
}
无论是那种情况下,上面的代码都能检测出弹出窗口是否被屏蔽并返回正确的结果而不会报错。
间歇调用和超时调用
JavaScript是单线程语言,但它允许通过设置超时值和间歇时间值来调度代码在特定的时刻执行。前者是在指定的时间过后执行代码,而后者是每隔指定的时间就执行一次代码。
超时调用需要使用window
对象的setTimeout()
方法,它接收两个参数,要执行的代码和毫秒表示的时间。其中,第一个参数可以是包含JavaScript代码的字符串(和在eval()
函数中使用的字符串一样),也可以是一个函数。示例:
//不推荐调用字符串
window.setTimeout("alert('Hello world!')", 1000);
//推荐使用函数调用
setTimeout(function () {
alert("Hello world!");
}, 1000);
之所以不推荐使用字符串,是因为字符串形式会造成性能损失。
第二个参数是表示等待多长时间的毫秒数,但经过该段事件后代码不一定会执行,JavaScript是单线程序解释器,因此一段时间内只能执行一段代码。为了控制要执行的JavaScript代码,就有了JavaScript任务队列的概念。这些任务会按照在任务队列中的顺序执行,setTimeout()
方法实际上是在多少毫秒后将该段代码添加到任务队列,如果此时任务队列为空,那么添加的代码会立即执行,如果不为空,则要等到前面的代码执行完再执行。调用setTimeout()
方法之后,该方法会返回一个数值ID,表示超时调用。这个超时调用ID是计划执行代码的唯一标识符,可以通过它来取消超时调用。要取消尚未执行的超时调用计划,可以调用clearTimeout()
方法,将超时调用ID传给它,如下所示:
//设置超时调用
var timeoutId = setTimeout(function () {
alert("Hello world!");
}, 2000);
//把它取消
clearTimeout(timeoutId);
只要是在指定的时间尚未过去之前调用clearTimeout()
,就可以完全取消超时调用。
超时调用的代码都是在全局作用域下执行的,因此函数中的this值在非严格模式下是window
,严格模式下是undefined
。
间歇调用和超时调用类似,只不过它会按照指定的时间间隔重复执行代码,直到间歇调用被取消或者页面被卸载。设置间歇调用的方法是setInterval()
,它接收的参数和setTimeout()
是相同的:要执行的代码和每次执行之前需要等待的毫秒数。示例:
//不推荐调用字符串
window.setInterval("alert('Hello world!')", 1000);
//推荐使用函数调用
setInterval(function () {
alert("Hello world!");
}, 1000);
与setTimeout()
方法相同,间歇调用也会返回一个间歇调用ID,这个ID可以传给clearInterval()
方法用于取消间歇调用。示例:
var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber() {
num++;
//如果执行次数达到了max设定的值,则取消后续尚未执行的调用
if (num == max) {
clearInterval(intervalId);
alert("Done!");
}
}
intervalId = setInterval(incrementNumber(), 500);
上面这个例子也可以使用超时调用来实现:
var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber() {
num++;
//如果执行次数未达到max设置的数值。则执行下一次超时调用
if (num < max) {
setTimeout(arguments.callee, 500);
} else {
alert("Done");
}
}
setTimeout(incrementNumber(), 500);
可见,在进行超时调用时,没有必要追踪超时调用ID,因为每次执行完代码以后,如果不再设置另一次超时调用,调用将会自动停止。一般认为,使用超时调用模拟间歇调用是一种最佳的调用方式。开发环境下,很少会使用真正的间歇调用,原因是一个间歇调用很可能在前一个间歇调用结束之前启动。
系统对话框
浏览器通过alert()
、confirm()
和prompt()
可以调用系统对话框向用户显示消息。通过这几个方法打开的对话框是同步和模态的,也就是说,显示这些对话框的时候代码会停止运行,而关掉这些对话框后代码又会恢复执行。
alert()
对话框一般用于提示错误信息,用户除了查看错误信息只能关闭对话框。
confirm()
对话框更像是“警告”,有两个按钮,ok和cancel,点击ok返回true,点击cancel或者右上角“x”关闭对话框返回false。示例:
if (confirm("你确定删除吗?")) {
alert("已经删除!");
} else {
alert("已取消!");
}
prompt()
提示用户输入一段文本,有两个按钮,ok和cancel,点击ok返回用户输入的文本,点击cancel或者右上角“x”关闭对话框返回null
。有两个参数,第一个参数表示提示用户输入的提示信息,第二个参数可以是文本输入框的默认值(可不写)。示例:
var result = prompt("输入你的名字:","Ethan");
if (result !== null) {
alert("欢迎你," + result);
} else {
alert("你取消了输入!");
}
对话框计数器:Chrome、Firefox4+和IE9+有了一个对话框计数器,当一个页面频繁跳出对话框,对话框下部就会出现一个复选框,选中可以取消该页面继续弹出对话框,重新刷新当前页面后对话框计数器也重置。
8.2 location对象
location
对象提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能。location
对象不只是window
的属性,也是document
的属性。换句话说,window.location
和document.location
引用的是同一个对象。它将URL解析为独立的片段。下表是location
对象的所有属性及方法:
location对象属性
- hash 设置或返回从井号 (#) 开始的 URL(锚)。
- host 设置或返回主机名和当前 URL 的端口号。
- hostname 设置或返回当前 URL 的主机名。
- href 设置或返回完整的 URL。
- pathname 设置或返回当前 URL 的路径部分。
- port 设置或返回当前 URL 的端口号。
- protocol 设置或返回当前 URL 的协议。
- search 设置或返回从问号 (?) 开始的 URL(查询部分)。
location对象方法:
- assign() 加载新的文档。
- reload() 重新加载当前文档。
- replace() 用新的文档替换当前文档。
查询字符串操作
书中的函数将location.search
返回的字符串分割,最后返回了一个对象,对象的属性及属性值就是参数及参数值。
位置操作
使用location
对象可以有很多种方式来改变浏览器的位置。首先,也就是最常用的方式,调用assign()
方法,传入一个URL:
location.assign("https://www.baidu.com");
注意:URL必须要加上前面的协议名,否则就是404错误。
使用location.assign()
方法可以立即打开URL并在浏览器的历史记录中添加一条新记录,下面的两条语句和使用location.assign()
方法效果是一样的:
window.location = "https://www.baidu.com";
location.href = window.location = "https://www.baidu.com";
最常用的就是使用location.href
属性。
修改了location
的任何一个属性之后,页面都会以新URL加载页面,同时在浏览器历史记录中添加一条新的记录,用户单击“后退”按钮将会回退到前一个页面,要禁止这种行为,需要使用location.replace()
方法。示例:
setTimeout(function () {
location.replace("https://www.baidu.com");
}, 3000);
这个方法接收一个url,结果是浏览器的位置改变,但是“回退”按钮显示禁用状态,即无法回退到上一个页面。同时,不会在历史记录中产生新的记录。
与位置有关的最后一个方法是reload()
。该方法接收一个参数(可选)true
,如果不传入true
,浏览器将会从缓存中重新加载当前文档;如果传入true
,浏览器将会从服务器重新加载当前文档。示例:
location.reload(); //重新加载(有可能从缓存中加载)
location.reload(true); //从服务器重新加载
位于reload()
方法之后的代码可能执行也可能不执行,这要取决于网络延迟和系统资源等因素,为此,最好把reload()
方法放在代码的最后一行。
8.3 navigator对象
每个支持JavaScript的浏览器都支持navigator
对象,只是每个浏览器中navigator对象的属性不尽相同,其中,所有浏览器都有的属性为userAgent
。
检查插件
除了IE浏览器,可以使用navigator
对象的plugins
数组检查插件,该数组的每一项都有如下四个属性:name
(插件名)、description
(插件描述)、filename
(插件的文件名)和length
(插件所处理的MIME类型数量)。
一般来说,name
属性中会包含检测插件必需的所有信息,但有时候也不完全如此。在检查插件时,需要像下面这样循环迭代每个插件并将插件的name
属性与给定的名字比较:
//检测插件(IE中无效)
function hasPlugin(name) {
name = name.toLowerCase();
for (var i=0;i<navigator.plugins.length;i++) {
if (navigator.plugins[i].name.toLowerCase().indexOf(name) >= -1) {
return true;
}
}
return false;
}
//检测Flash
alert(hasPlugin("Flash"));
//检测Adblock Plus
alert(hasPlugin("Adblock Plus"));
传入要检测的插件名,转换为小写,然后迭代plugins
数组,通过indeOf()
检测每个name
属性,以确定传入的名称是否在字符串的某个地方出现过。
检测IE的插件比较麻烦,因为IE不支持Netscape式的插件,在IE中检查插件的唯一方式是使用专有的ActiveXObject
类型,并尝试创建一个特定插件的实例。IE是以COM对象的方式来实现插件的,而COM对象使用唯一标识符来标识。因此想要检查特定的插件,首先要知道插件的COM标识符。例如,Flash的标识符为ShockwaveFlash.ShockwaveFlash
。示例:
//检测IE中的插件
function hasIEPlugin(name) {
try {
new ActiveXObject(name);
return true;
} catch (ex) {
return false;
}
}
//检测Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash")); //true
函数接收一个COM标识符作为参数,在函数中首先会尝试创建一个COM对象,创建成功则返回true
,创建失败则返回false
。试图创建一个不存在的COM对象时会抛出错误,因此使用了try……catch块。
鉴于两种检测方式差别较大,因此典型的做法是针对每个插件分别创建检测函数,而不是使用通用的检测方式,示例:
function hasPlugin(name) {
name = name.toLowerCase();
for (var i = 0; i < navigator.plugins.length; i++) {
if (navigator.plugins[i].name.toLowerCase().indexOf(name) >= -1) {
return true;
}
}
return false;
}
//检测IE中的插件
function hasIEPlugin(name) {
try {
new ActiveXObject(name);
return true;
} catch (ex) {
return false;
}
}
//检测所有浏览器中的Flash
function hasFlash() {
var result = hasPlugin("Flash");
if (!result) {
result = hasIEPlugin("ShockwaveFlash.ShockwaveFlash");
}
return result;
}
//检测Flash
alert(hasFlash()); //IE、Chrome返回true,Firefox返回false
plugins
集合有一个名叫refresh()
方法,用于刷新plugins
以反映最新安装的插件。这个方法接收一个参数:表示是否应该重新加载页面的一个布尔值。如果这个值设置为true
,则会重新加载包含插件的所有页面;否则,只更新plugins
集合,不重新加载页面。
注册处理程序
registerContentHandler()
和registerProtocolHandler()
方法
8.4 screen对象
JavaScript中有几个对象在编程中用处不大,而screen
对象就是其中之一。这个对象基本上用于表明客户端的能力,其中包括浏览器窗口外部的显示器的信息,如像素宽度和高度等。screen
对象的属性绝大多数为只读的。示例:
//使用screen对象的属性调整浏览器的宽度和高度
window.resizeTo(screen.availWidth, screen.availHeight);
测试只有IE有效,Firefox和Chrome都禁止调整浏览器的大小。
涉及移动设备,ios和android也不相同。
8.5 history对象
history
对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。因为history
是window
对象的属性,所以每个浏览器的窗口、每个标签页乃至每个框架都有自己的history
对象和window
对象关联。出于安全方面的考虑,开发人员无法得知用户浏览过的URL,不过,借由用户浏览过的页面列表,同样可以在不知道URL的情况下实现后退和前进。
go()
方法:接收一个参数,参数为整数。负数表示向后跳转(后退),正数表示向前跳转(前进)。示例:
//后退一页
history.go(-1);
//前进一页
history.go(1);
除了整数外,还可以接收字符串作为参数,此时浏览器会跳转到包含该字符串的第一个位置——可能是前进也可能是后退,具体要看哪个位置更近。如果历史记录中不包含该字符串,则什么也不做。示例:
history.go("baidu"); //跳转到最近的baidu页面
另外,还有两个更简单的back()和forward()方法来代替go():
//后退一页
history.back();
//前进一页
history.forward();
除此之外,history
还有一个length
属性,保存了历史记录的数量。这个数量包括所有历史记录,即所有向前或者向后的记录。可以用这个属性判断当前页面是不是第一个打开的标签页、第一个页面或者框架中第一个加载的页面。示例:
if (history.length == 0) {
alert("这是你打开的第一个页面!");
}
length
属性等于0时,表示当前页面是第一个打开的标签页,或者第一个页面或者框架中第一个加载的页面。
虽然history
并不常用,但是在创建自定义的“后退”和“前进”按钮,或者需要确定当前页面是否是用户历史记录的第一个页面时,还是必须使用它。