BOM
Window对象是客户端JavaScript程序的全局对象。
11.1 计时器
setTimeout()
和
setInterval()
可以用来注册在指定的时间之后单次或重复调用的函数。两者都是客户端JavaScript中的全局函数,也就是Window对象的方法。
(1)setTimeout()
setTimeout()
方法用来实现一个函数在指定的毫秒数之后运行,返回一个值,这个值可以传递给clearTimeout()用于取消这个函数的执行。
var times = setTimeout(function(){},1000); //1000毫秒后执行
clearTimeout(times); //取消执行
(2)setInterval()
setInterval()方法和setTimeout()一样,只不过这个函数会在指定毫秒数的间隔里重复调用,也返回一个值,这个值传递给clearInterval(),用于取消后续函数的调用。
var times = setInterval(function(){},1000); //每隔1000毫秒调用一次function
clearInterval(times); //取消后续函数执行
注意:如果以0毫秒的超时时间来调用setTimeout(),那么指定的函数不会立刻执行。相反,会把它放到队列中,等到前面处于等待状态的事件处理程序全部执行完成后,再“立即”调用它。
11.2 浏览器定位和导航
Window对象的
location
属性引用的是
Location
对象,它表示该窗口中当前显示的文档的URL,并定义了方法来使窗口载入新的文档。
Document对象的location属性也引用到Location对象:
window.location === document.location //总是返回true
Document对象也有一个URL属性,是文档首次载入后保存该文档的URL的静态字符串。如果定位到文档中的片断标识符(如#top),Location对象会做相应的更新,而document.URL属性却不会改变。
11.2.1 解析URL
Location对象href属性是一个字符串,href属性包含ULR的完整文本。Location对象的toString()方法返回href属性的值,因此在会隐式调用toString()的情况下,可以用location代替location.href。
// 当前网址为 http://user:passwd@www.example.com:4097/path/a.html?x=111#part1location.href // "http://user:passwd@www.example.com:4097/path/a.html?x=111#part1"
location.protocol // "http:"
location.host // "www.example.com:4097"
location.hostname // "www.example.com"
location.port // "4097"
location.pathname // "/path/a.html"
location.search // "?x=111"
location.hash // "#part1"
location.user // "user"
location.password // "passed"
protocol、host、hostname、port、pathname和search属性是“URL分解”属性,是可写的,对它们重新赋值的话,会改变URL的位置,并且浏览器会载入一个新的文档。
Location
对象的方法:
location.assign()
:使窗口载入并显示指定的URL中的文档。location.replace()
:和assign()方法类似,但它在载入新文档之前会从浏览历史中把当前文档删除。这样“后退”按钮就不会把浏览器带回到原始文档。location.reload()
:重新载入当前文档,可传入一个布尔值为参数,默认false。如果为true,则优先从服务器重新加载;否则优先从本地缓存中重新加载。
当然,我们还有更直接跳转到新页面的方法:
location = 'http://baidu.com';
//或者
location.href = 'http://baidu.com';
纯粹的片断标识符是相对URL的一种类型,它不会让浏览器载入新文档,而是使浏览器滚动到文档的某个位置。
注意:#top标识符是个特殊值:如果文档中没有元素的ID是“top”,它会让浏览器滚动到文档开始处。
location = '#top'; //跳转到文档的顶部
11.3 浏览历史
Window对象的history属性引用的是该窗口的History对象。History对象是用来把窗口浏览历史用文档和文档状态列表的形式表示。
History对象的length属性表示浏览历史表中的元素数量。比如你在当前窗口访问了三个不同的网址,那么history.length就等于3。
History对象还提供了一系列的方法,让我们在历史记录中自由前进和后退。
- back():移动到上一个访问页面,等同于浏览器的后退键。
- forward():移动到下一个访问页面,等同于浏览器的前进键。
-
go():接受一个整数作为参数,移动到该整数指定的页面,比如go(1)相当于forward(),go(-1)相当于back()。
如果移动的位置超出了访问历史的边界,以上三个方法并不报错,而是默默的失败。
history.go(0)相当于刷新当前页面。
history.go(0)
注意:如果窗口包含多个子窗口(比如 >元素),子窗口的浏览历史会按时间顺序穿插到主窗口的历史中。这就是意味着主窗口调用back()可能会导致其中一个子窗口往回跳转到前一个显示的文档,而主窗口保留当前状态不变。
HTML5为history对象添加了两个新方法,用来添加和修改历史记录条目。
history.pushState()
:会改变referrer的值,而在你调用方法后创建的 XMLHttpRequest 对象会在 HTTP 请求头中使用这个值。referrer的值则是创建 XMLHttpRequest 对象时所处的窗口的URL。history.replaceState()
:会修改当前历史记录条目而并非创建新的条目
(1)history.pushState()
history.pushState方法接受三个参数,依次为:
state:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。
假定当前网址是example.com/1.html,我们使用pushState方法在浏览记录(history对象)中添加一个新记录。
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
添加上面这个新记录后,浏览器地址栏立刻显示
example.com/2.html
,但并不会跳转到2.html,甚至也不会检查2.html是否存在,它只是成为浏览历史中的最新记录。
假定这时你访问了google.com
,然后点击了倒退按钮,页面的url将显示2.html,但是内容还是原来的1.html。你再点击一次倒退按钮,url将显示1.html,内容不变。
总之,pushState方法不会触发页面刷新,只是导致history对象发生变化,地址栏会有反应。
如果pushState的url参数,设置了一个新的锚点值(即hash),并不会触发hashchange事件。如果设置了一个跨域网址,则会报错。
(2)history.replaceState()
history.replaceState方法的参数与pushState方法一模一样,区别是它修改浏览历史中当前纪录。
假定当前网页是
example.com/example.html
。
history.pushState({page: 1}, 'title 1', '?page=1');
history.pushState({page: 2}, 'title 2', '?page=2');
history.replaceState({page: 3}, 'title 3', '?page=3');
history.back()
// url显示为http://example.com/example.html?page=1
history.back()
// url显示为http://example.com/example.html
history.go(2)
// url显示为http://example.com/example.html?page=3
(3)history.state属性
history.state
属性返回当前页面的state对象。
history.pushState({page: 1}, 'title 1', '?page=1');
history.state // { page: 1 }
(4)popstate事件
每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。
需要注意的是,仅仅调用pushState方法或replaceState方法 ,并不会触发该事件,只有用户点击浏览器倒退按钮和前进按钮,或者使用JavaScript调用back、forward、go方法时才会触发。另外,该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发。
使用的时候,可以为popstate事件指定回调函数。这个回调函数的参数是一个event事件对象,它的state属性指向pushState和replaceState方法为当前URL所提供的状态对象(即这两个方法的第一个参数)。
window.onpopstate = function (event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
};
// 或者
window.addEventListener('popstate', function(event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
});
上面代码中的event.state,就是通过pushState和replaceState方法,为当前URL绑定的state对象。
这个state对象也可以直接通过history对象读取。
var currentState = history.state;
注意:页面第一次加载的时候,在load事件发生后,Chrome和Safari浏览器(Webkit核心)会触发popstate事件,而Firefox和IE浏览器不会。
11.4 浏览器和屏幕信息
Window对象的navigator和screen属性,分别引用的是Navigator和Screen对象。
11.4.1 Navigator对象
Window对象的navigator属性引用的是包含浏览器产商和版本信息的Navigator对象。
Navigator对象的属性
(1)navigator.appName、navigator.appVersion
appName是Web浏览器的全称。在IE中,是“Microsoft Internet Explorer”。在其他浏览器中,是“Netscape”。
appVersion此属性通常以数字开始,并跟着包含浏览器产商和版本信息的详细字符串。字符串前面的数字通常是4.0或5.0,表示它是第4或第5代兼容的浏览器。
(2)navigator.userAgent
navigator.userAgent属性返回浏览器的User-Agent字符串,标示浏览器的厂商和版本信息。它包含了appVersion中的所有信息。
下面是Chrome浏览器的userAgent。
navigator.userAgent
//Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
利用这个属性,我们还可以判断手机浏览器的类型。
if (/AppleWebKit.*Mobile/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|ZTE/.test(navigator.userAgent))) {
try {
if (/Android|Windows Phone|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
//手机浏览器
} else if (/iPad/i.test(navigator.userAgent)) {
//ipad
} else {}
} catch (e) {}
} else {
//非手机浏览器
}
如果你只是简单的判断是否手机浏览器。
var ua = navigator.userAgent.toLowerCase();
if(/mobi/i.test(ua)){
//手机浏览器
}else{
//非手机浏览器
}
(3)navigator.platform
返回用户的操作系统信息
比如我的:
navigator.platform
//win32
(4)navigator.onLine
表示浏览器当前是否连接到网络。返回一个布尔值。
(5)navigator.geolocation
返回一个Geolocation对象,包含用户地理位置信息。详情请看《HTML5 API》
(6)navigator.javaEnabled()
javaEnabled方法返回一个布尔值,表示浏览器是否能运行Java Applet小程序。
(7)navigator.cookieEnable()
cookieEnabled方法返回一个布尔值,表示浏览器是否能储存Cookie。
11.4.2 Screen对象
Window对象的screen属性引用的是Screen对象,它提供有关窗口显示的大小和可用的颜色数量的信息。
(1)screen.width、screen.height
screen.width和screen.height分别返回以像素为单位的窗口大小(设备的宽高)。
(2)screen.availHeight、screen.availWidth
screen.availHeight和screen.availWidth属性返回屏幕可用的高度和宽度,单位为像素。它们的值为屏幕的实际大小减去操作系统某些功能占据的空间,比如系统的任务栏。
(3)screen.colorDepth
screen.colorDepth属性返回屏幕的颜色深度,一般为16(表示16-bit)或24(表示24-bit)。
11.5 对话框
Window对象提供了3个方法来向用户显示简单的对话框。
alert()
:向用户显示一条消息并等待用户关闭对话框。confirm()
:同样显示一条消息,要求用户单击“确认”或“取消”按钮,并返回一个布尔值。prompt()
:同样显示一条消息,等待用户输入字符串,并返回这个字符串。
这三个方法都具有堵塞效应,一旦弹出对话框,整个页面就是暂停执行,等待用户做出反应。
(1)alert()
alert(1);
(2)confirm()
var c = confirm('确认登录');
confirm的一个用途是,当用户离开当前页面时,弹出一个对话框,询问用户是否真的离开。
window.onunload = function() {
return confirm('你确定要离开当面页面吗?');
}
(3)prompt()
// 格式
var result = prompt(text[, default]);
//实例
var result = prompt('您的年龄?',18);
prompt方法的返回值是一个字符串(有可能为空)或者null,具体分成三种情况。
用户输入信息,并点击“确定”,则用户输入的信息就是返回值。
用户没有输入信息,直接点击“确定”,则输入框的默认值就是返回值。
用户点击了“取消”(或者按了Esc按钮),则返回值是null。
注意:这些对话框中显示的文本是纯文本,而不是HTML格式的文本。只能使用空格、换行符或各种标点符号来格式化这些对话框。
11.6 错误处理
Window对象的onerror属性是一个事件处理程序,当未捕获的异常传播到调用栈上时就会调用它,并把错误信息输出到浏览器的JavaScript控制台上。
window.onerror = function (message, filename, lineno, colno, error) {
console.log("出错了!--> %s", error.stack);
};
五个参数的含义:
message:出错信息
filename:出错脚本的网址
lineno:行号
colno:列号
error:错误对象
老式浏览器只支持前三个参数。
并不是所有的错误,都会触发JavaScript的error事件(即让JavaScript报错),只限于以下三类事件。
- JavaScript语言错误
- JavaScript脚本文件不存在
- 图像文件不存在
以下两类事件不会触发JavaScript的error事件。
- CSS文件不存在
- iframe文件不存在
注意:onerror处理程序的返回值也很重要。如果onerror处理程序返回false,它通知浏览器事件处理程序已经处理了错误,不需要其他操作。也就是说,浏览器不应该显示它自己的错误信息。遗憾的是,由于历史原因,Firefox里的错误处理程序必须返回true来表示它已经处理了错误。
11.7 多窗口和窗体
由于网页可以使用
<iframe>
嵌套多个网页,因此一个网页之中会形成多个窗口。另一情况是,子网页之中又嵌入别的网页,形成多级窗口。每个窗口的Window对象都是独立的,互不干扰。
浏览器提供了一些特殊变量,用来返回其他窗口。
top:顶层窗口,即最上层的那个窗口
parent:父窗口
self:当前窗口,即自身
下面的代码可以判断当前窗口是否是顶层窗口
window.top === window.self
与这些变量对应,浏览器还提供一些特殊的窗口名,供open方法、<a>
标签、<form>
标签等引用。
_top:顶层窗口
_parent:父窗口
_blank:新窗口
11.7.1 打开和关闭窗口
使用Window对象的open()方法可以打开一个新的浏览器窗口。Window.open()载入指定的URL到新的或已存在的窗口中,并返回代表那个窗口的Window对象。
open方法一共可以接受四个参数。
第一个参数:字符串,表示新窗口的网址。如果省略,默认网址就是
about:blank
。
第二个参数:字符串,表示新窗口的名字。如果该名字的窗口已经存在,则跳到该窗口,不再新建窗口。如果省略,就默认使用_blank,表示新建一个没有名字的窗口。
第三个参数:字符串,内容为逗号分隔的键值对,表示新窗口的参数,比如有没有提示栏、工具条等等。如果省略,则默认打开一个完整UI的新窗口。
第四个参数:布尔值,表示第一个参数指定的网址,是否应该替换history对象之中的当前网址记录,默认值为false。显然,这个参数只有在第二个参数指向已经存在的窗口时,才有意义。
var modal = window.open(
'example.html',
'modalWindow',
'height=200,width=300'
);
modal.window.name //modalWindow
window.close方法用于关闭当前窗口,一般用来关闭window.open方法新建的窗口。
modal.close();
该方法只对顶层窗口有效,iframe框架之中的窗口使用该方法无效。
11.7.2 窗体
窗体是通过
<iframe>
元素创建的,我们可以像获取其他元素一样,获取一个表示
<iframe>
的元素对象,同时,
<iframe>
元素有
contentWindow
属性,引用该窗体的Window对象。
<iframe id='f'></iframe>
var f = document.getElementById('f');
var win = f.contentWindow; //子窗体的Window对象
var doc = f.contentDocument; //等同于f.contentWindow.document
//获取子窗体的变量和属性
f.funciton()
f.title
iframe嵌入窗口的window对象,有一个frameElement属性,返回它在父窗口中的DOM节点。对于顶级窗口,该属性等于null。
win.frameElement === f //true
window.frameElement === null //true
当然,也可以使用Window对象的frames属性,它引用自身包含的窗口或窗体的子窗体。返回一个类数组对象。
var f = window.iframes[0];
注意:frames[]数组里的元素是Window对象,而非
<iframe>
元素。
利用这个属性,实现窗口之间的互相引用。比如,frames[0]返回第一个子窗口,frames[1].frames[2]返回第二个子窗口内部的第三个子窗口,parent.frames[1]返回父窗口的第二个子窗口。
如果
<iframe>
元素设置了name或id属性,那么属性值会自动成为(Window对象的属性)全局变量,并且可以通过window.frames属性引用,返回子窗口的window对象。
// HTML代码为<iframe id="myFrame">
myFrame // [HTMLIFrameElement]
frames.myframe === myFrame // true
另外,name属性的值会自动成为子窗口的名称,可以用在window.open方法的第二个参数,或者
<a>
和
<frame>
标签的target属性。