第8章 BOM——浏览器对象模型
- window对象——BOM的核心
BOM的核心对象是window,它表示浏览器的一个实例。
由于window对象同时扮演着ECMAScript中Global对象的角色,因此所有全局作用域中声明的变量、函数都会变成window对象的属性和方法。
var age = 29;
function sayAge(){
alert(this.age);
}
alert(window.age); //29
sayAge(); //29
window.sayAge(); //29
抛开全局变量会成为window对象的属性不谈,定义全局变量与在window对象上直接定义属性还是有一点差别:全局变量不能通过delete操作符删除,而直接在window对象上定义的属性可以。
窗口位置:
var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;
窗口大小:
跨浏览器确定一个窗口的大小不是一件简单的事。各个浏览器对窗口大小有不同的定义,即使相同的属性,在各个浏览器中表现的也不同。
虽然最终无法确定浏览器窗口本身的大小,但却可以取得页面视口的大小。
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;
}
}
window.open()方法既可以导航到一个特定的URL,也可以打开一个新的浏览器窗口。
这个方法可以接收4个参数:要加载的URL、窗口目标、一个特性字符串以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。
window.open("http://www.baidu.com/", "topFrame");
//等同于<a href="http://www.baidu.com" target="topFrame"></a>
第三个参数是一个都喊分割的设置字符串,表示在新窗口中都显示那些特性。
window.open("http://www.wrox.com/","wroxWindow","height=400,window=400,top=10,left=10,resizable=yes");
//这行代码会打开一个新的可以调整大小的窗口,窗口初始大小为400*400像素,并且距屏幕上沿和左边各10像素。
对于浏览器的主窗口,如果没有得到用户的允许是不能关闭它的,但是弹出窗口也就是通过window.open()打开的弹出窗口,可以调用top.close()在不经用户允许的情况下关闭自己。
但是有个问题:大多数浏览器都内置有弹出窗口屏蔽程序。用户可以将绝大多数不想看到的弹出窗口屏蔽掉。
在弹出窗口被屏蔽时,可以考虑两种可能性。
如果是浏览器内置的屏蔽程序阻止的弹出窗口,那么window.open()很可能会返回null;如果是浏览器扩展或其他程序阻止的弹出窗口,window.open()会抛出错误。
因此想要准确地检测出弹出窗口是否被屏蔽,必须在检测返回值的同时,将对window.open()的调用封装在一个try-catch块中
var blocked = false;
try{
var wroxWin = window.open("http://www.wrox.com","_blank");
if(wroxWin == null){
blocked = true;
}
}catch (ex) {
blocked = true;
}
if(blocked){
alert("The popup was blocked!");
}
间歇调用和超时调用
JavaScript是单线程语言,但它允许通过设置超时值和间隙时间值来调用代码在特定的时刻执行。
超时调用需要使用window对象的setTimeout()方法,它接受两个参数:要执行的代码和以毫秒表示的时间—即在执行代码前需要等待多少毫秒。
setTimeout(function(){
alert(“Hello world!”);
}, 1000);
第一个参数通常是一个函数,第二个参数是一个表示等待多长时间的毫秒数,但经过该时间后指定的代码不一定会执行。
setTimeout()的第二个参数告诉JavaScript再过多长时间把当前任务添加到队列中,如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么它就要等前面的代码执行完了以后再执行。
要取消尚未执行的超时调用计划,可以调用clearTimeout()方法。
//设置超时调用
var timeoutId = setTimeout(function(){
alert(“Hello world!”);
}, 1000);
//注意:把它取消
clearTimeout(timeoutId); //在设置超时调用之后马上又调用了clearTimeout(),结果就跟什么也没发生一样。
只要是在指定的时间尚未过去之前调用clearTimeout(),就可以完全取消超时调用。
间歇调用需要使用window对象的setInterval()方法,它会按照执行的时间间隔重复执行代码,直至间歇调用被取消或者页面被卸载。
setInterval(function(){
alert(“Hello world!”);
}, 10000);
取消间歇调用的重要性要远远高于取消超时调用,因为在不加干涉的情况下,间歇调用将会一直执行到页面卸载。
var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber(){
num++;
//如果执行次数达到了max设定的值,则取消后续尚未执行的调用
if(num == max){
clearInterval(intervalId);
alert(“Done”);
}
}
intervalId = setInterval(incrementNumber, 500);
变量num每半秒钟递增一次,当递增到最大值时就会取消先前设定的间歇调用。
这个模式也可以使用超时调用来实现。
var num = 0;
var max = 10;
function incrementNumber(){
num++;
//如果执行次数达到了max设定的值,则设置另一次超时调用
if(num < max){
setTimeout(incrementNumber, 500);
}else{
alert(“Done”);
}
}
setTimeout(incrementNumber, 500);
系统对话框
浏览器通过alert()、confirm()和prompt()方法可以调用系统对话框向用户显示消息。
它们的外观由操作系统及(或)浏览器设置决定,而不是由CSS决定。
此外,通过这几句歌方法打开的对话框都是同步和模拟的,也就是说,显示这些对话框的时候代码会停止执行,而关掉这些对话框后代码又会恢复执行。
alert(“Hello world!”);
confirm(“Are you sure?”);
prompt(“What’s your name?”,”her”);
2.location对象
location是最有用的BOM对象之一,它提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能。
虽然通过上面的属性可以访问到location对象的大多数信息,但其中访问URL包含的查询字符串的属性并不方便。为此可以像下面这样创建一个函数来解析查询字符串,返回包含所有参数的一个对象:
function getQueryStringArgs(){
//取得查询字符串并去掉开头的问号
var qs = (location.search.length > 0 ? location.search.substring(1) : “”),
//保存数据的对象
args = {},
//取得每一项
items = qs.length ? qs.split(“&”) : [],
item = null,
name = null,
value = null,
//在for循环中使用
i = 0,
len = items.length;
//逐个将每一项添加到args对象中
for(i=0;i<len;i++){
item = items[i].split("=");
name = decodeURLComponent(item[0]);
value = decodeURLComponent(item[1]);
if(name.length){
args[name] = value;
}
}
return args;
}
//假设查询字符串是?q=javascript&num=10
var args = getQueryStringArgs();
alert(args["q"]); //"javascript"
alert(args["name"]); //"10"
在改变浏览器位置的方法中,最常用的设置location.href属性。
//假设初始URL为http://www.wrox.com/WileyCDA/
//跳转到http://www.wrox.com
location.href = "http://www.wrox.com";
//将URL修改为"http://www.wrox.com/WileyCDA/#section1"
location.hash = "#section1";
//将URL修改为"http://www.wrox.com/WileyCDA/?q=javascript"
location.search = "?q=javascript";
//将URL修改为"http://www.yahoo.com/WileyCDA/"
location.hostname = "http://www.yahoo.com";
//将URL修改为"http://www.yahoo.com/mydir/"
location.pathname = "mydir";
//将URL修改为"http://www.yahoo.com:8080/WileyCDA/"
location.port = "8080";
每次修改location的属性(hash除外),页面都会以新URL重新加载。
上述任何一种方式修改URL之后,浏览器的历史记录中就会生成一条新纪录,因此用户通过单击"后退"按钮都会导航到前一个页面。
要禁用这种行为,可以通过replace()方法,不会再历史记录中生成新纪录。
reload()方法,作用是重新加载当前显示的页面。
如果要强制从服务器重新加载,则需要像下面这样子为该方法传递参数true。
location.reload(); //重新加载(有可能从缓存中加载)
location.reload(true); //重新加载(从服务器重新加载)
位于reload()调用之后的代码可能会也可能不会执行,这要取决于网络延迟或系统资源等因素。为此最好将reload()放在代码最后一行。
3.history对象
history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。
出于安全方面的考虑,开发人员无法得知用户浏览过的URL。
使用go()方法可以在用户的历史记录中任意跳转,可以向后也可以向前。
history.go(-1);//后退一页
history.go(1);//前进一页
history.go(2);//前进两页
history.go("wrox.com");//跳转到最近的wrox.com页面
history.back();//后退一页
history.forward();//前进一页
也可以给go()方法传递一个字符串参数,会跳转到历史记录中包含该字符串的第一个位置,可能前进可能后退,看哪个位置最近,如果历史记录中不包含该字符串,则什么都不做。
确定用户是否一开始就打开了你的页面
if(history.length == 0){
//这应该是用户打开窗口后的第一个页面
}
小结
浏览器对象(BOM)以window对象为依托,表示浏览器窗口以及页面可见区域。
在使用框架时,每个框架都有自己的window对象以及所有构造函数及其他函数的副本,每个框架都保存在frames集合中,可以通过位置或通过名称来访问。
top对象始终指向最外围的框架,也就是整个浏览器窗口。
parent对象表示包含当前框架的框架,而self对象则回指window。
使用location对象可以通过编程方式来访问浏览器的导航系统。实质性相应的属性,可以逐段或整体性地修改浏览器的URL。
调用replace()方法可以导航到一个新URL,同时该URL会替换浏览器历史记录中当前显示的页面。
navigator对象提供了与浏览器有关的信息。
今天就先到这儿咯,今天下班晚,就先啃到这儿啦
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。