阅读(1250) (0)

JavaScript学习笔记整理(11):window对象

2017-06-19 12:02:23 更新
      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)

注意:如果窗口包含多个子窗口(比如<iframe>元素),子窗口的浏览历史会按时间顺序穿插到主窗口的历史中。这就是意味着主窗口调用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属性。