BOM

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属性。

文章导航