第八章 BOM
1. window对象 :
BOM的核心对象是 window,他表示浏览器的一个实例。在浏览器中,window 对象有双重角色,它既是通过JavaScript访问浏览器窗口的一个接口,又是ECMAScript规定的 Global 对象。这意味着在网页中定义的任何一个对象,变量,函数,都以 window 作为其 Global 对象。
2. 全局作用域 :
var age = 29;
function sayAge(){
alert(this.age);
}
alert(window.age); //29
sayAge(); //29
window.sayAge(); //29
3. 窗口关系及框架 :
如果页面包含框架,那么每个框架都将拥有自己的 window 对象,并且保存在 frames 集合中,在 frames 集合中,可以通过数值索引(从0开始,从左到右,从上到下)或者框架名称来访问相应的 window 对象,每个 window 对象都有一个 name 属性,其中包含框架的名称。
<html>
<head>
<title>Framest Example</title>
</head>
<frameset row = "160,*">
<frame src = "frame.htm" name = "topFrame">
<frameset cols = "50%,50%">
<frame src = "bottomLeft.htm" name = "leftFrame">
<frame src = "bottomRight.htm" name = "rightFrame">
</frameset>
</frameset>
</html>
以上代码创建了一个框架集,其中一个框架居上,两个居下。下面我们来列举几种方法用来表示这三个框架集。
上部的框架集:
window.frames[0]
window.frames[“topFrame”]
top.frames[0]
top.frames[“topFrame”]
frames[0]
frames[“topFrame”]
下部的左侧框架集:
window.frames[1]
window.frames[“leftFrame”]
top.frames[1]
top.frames[“leftFrame”]
frames[1]
frames[“leftFrame”]
下部的右侧框架集:
window.frames[2]
window.frames[“rightFrame”]
top.frames[2]
top.frames[“rightFrame”]
frames[2]
frames[“rightFrame”]
这里来解释下 top,top是一个对象,始终指向最外层的框架,也就是浏览器窗口。
与 top 相对的另一个 window 对象是 parent,顾名思义,parent 对象始终指向当前框架的直接上层框架。在某些情况下,parent 有可能等于 top,但在没有框架的时候,parent 肯定等于 top(此时它们都等于 window)
另外,与框架有关的最后一个对象是 self,它始终指向 window,实际上 self 和 window 对象可以互换着使用。
最后,要说明的是这些对象都是 window 的属性,可以通过 window.top,window.parent 等形式来访问。同时,这也意味着可以将不同层次的 window 对象连辍起来,如 window.parent.parent.frames[0]。
4. 窗口位置 :
用来确定和修改窗口位置属性和方法有很多,先来说获取窗口位置的方法...
比如 IE,Safari,Opera,Chrome提供了 screenLeft 和 screenTop 属性,分别用于表示窗口相当于屏幕左边和上边的位置.
fireFox则使用 screenX 和 screenY 来表示。
所以,万全之策应该可以跨浏览器来取得窗口位置。
var leftPos = (typeof window.screenleft == "number") ? window.screenleft : window.screenX;
var rightPos = (typeof window.screenright == "number") ? window.screenright : window.screenY;
接下来说改变窗口位置的方法:
- moveBy() : 接收两个参数,分别是水平和垂直所要移动的像素数。
- moveTO() : 接收两个参数,分别是新位置的X坐标值和Y坐标值。
//将窗口移动到屏幕左上角
window.moveTo(0,0);
//将窗口向下移动100像素
window.moveBy(0,100);
//将窗口向左移动50像素
window.moveBy(-50,0);
需要说明的是,这两个方法可能会被浏览器给禁用,而且这两个方法都不适用于框架,只适用于window对象使用。
5. 窗口大小 :
窗口大小分两种,一种是获取整个浏览器的宽和高,这时就要用到 outerHeight 和 outerWidth 属性。
另一种是除去工具栏,状态栏,边框等占位元素后剩余的净长宽,这时要用到 innerHeight 和 innerWidth 属性。
6. 导航和打开窗口 :
window.open() 方法接收4个参数 : 要加载的URL,窗口目标,一个特性字符串以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。通常只需传入一个参数,最后一个参数只在不打开新窗口的情况下使用。
//等同于<a href = "http://www.fanyank.com" target = "topFrame"></a>
window.open("http://www.fanyank.com","topFrame");
调用这行代码,就如同用户点击了 href 属性为 http://www.fanyank.com/ , target 属性为 ”topFrame” 的链接,如果有一个名叫“topFrame”的框架或者窗口,就会在该窗口或框架中加载这个URL;否则,就会创建一个名叫“topFrame”的新窗口。
如果利用该方法创建了一个新窗口,那么那么第三个参数就是用来调整新窗口的各项属性的,如果没有第三个参数,将会创建一个默认的新窗口。
第三个参数是一个逗号分隔的设置字符串,下表列出了可以出现在这个字符串的设置选项。
注意 :整个特性字符串中不允许出现空格
window.open("http://www.fanyank.com/","newWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
这行代码会打开一个新的可以调节大小的窗口,窗口的初始大小为400*400像素,并且距离屏幕上边和左边各10像素。
window.open() 方法会返回一个指向新窗口的引用。引用的对象与其他的 window 对象大致类似,但我们可以对其进行更多的控制。例如,有的浏览器在默认的情况下可能不允许我们针对主浏览器窗口调节大小或移动位置,但却允许我们针对通过 window.open() 创建的窗口调节大小和移动位置。通过这个返回对象,可以像操作其他窗口一样操作新打开的窗口。
var newObject = window.open("http://www.fanyank.com/","newWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
//调整大小
newObject.resizeTo(500,500);
//移动位置
newObject.moveTo(100,100);
//关闭新打开的窗口
newObject.close();
7. 间歇调用和超时调用 :
JavaScript是单线程语言,但它允许通过设置超时值和间歇时间值来调度代码在特定的时刻执行。
-
超时调用 : 在指定的时间过后执行代码。
超时调用需要使用 window 对象的 setTimeout() 方法,该方法接收两个参数:要执行的代码和以毫秒表示的时间,其中第一个参数可以是一个包含JavaScript代码的字符串(和 eval() 函数中使用的字符串一样),也可以是一个函数。
//不建议传递字符串,这样做可能会损失性能
setTimeout("alert('Hello world!')",1000);
//推荐的调用方式
setTimeout(function(){
alert("Hello world!");
},1000);
调用 **setTimeout()** 之后该方法会返回一个数值ID,表示超时调用。这个超值调用ID是计划执行代码的唯一标识符,可以用它来取消超时调用。
可以调用 **clearTimeout()** 方法来取消超时调用。
```javascript
//设置超时调用
var timeoutId = setTimeout(function(){
alert("Hello world!");
},1000);
//取消超时调用
clearTimeout(timeoutId);
-
间歇调用 : 每隔一段时间就执行一次代码。
间歇调用要使用 window 对象的 setInterval() 方法,接受的参数与 setTimeout() 相同,要执行的代码和每次执行之前需要等待的毫秒数。
//和上面一样,不建议传递字符串
//推荐调用方式
setInterval(function(){
alert("Hello world!");
},10000);
调用 setInterval 方法后也会返回一个间歇调用ID,该ID也是用来在将来的某个时刻取消间歇调用,但是在不加干涉的情况下,间歇调用将一直进行,直到页面关闭。
var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber(){
if(num == max){
clearInterval(intervalId);
alert("Done");
}
}
intervalId = setInterval(incrementNumber,1000);
需要说明的是,在开发中,很少真正的使用间歇调用,原因是后一个间歇调用可能会在前一个间歇调用之前启动。解决方法是我们可以通过超时调用来模拟间歇调用。
var num = 0;
var max = 10;
function incrementNumber(){
num++;
if(num < max){
setTimeout(incrementNumber,1000);
}
else
alert("Done");
}
setTimeout(increment,1000);
8. 系统对话框 :
- alert() : 这里不再赘述。
- confirm() : 用户将有两个选择(确定和取消),用户点击后,可以通过检查 confirm() 方法返回的布尔值来确定用户的点击行为。
if(confirm("Are you sure"))
{
alert("I'm glad to hear you're sure!");
}
else
{
alert("I'm sorry to hear you're not sure");
}
- prompt() : 用于提示用户输入一些内容,提示框中除了有确定和取消按钮外,还有一个文本框来接受用户的输入。
该方法接受两个参数,要显示给用户的文本提示和文本输入域的默认值(可以是一个空字符串)
返回值:返回用户所输入的值
var result = prompt("What's your name","Michael");
if(result !== null){
alert("Welcome," + result);
}
9. location对象 :
location 对象是最有用的BOM对象之一,它提供了与当前窗口加载的文档有关的信息,还提供了一些导航功能。它的作用还表现在讲URL解析为独立的片段,让开发人员可以通过不同的属性来访问这些字段。下表列出了 location 对象的所有属性。
来看一个完整的URL
http://www.wrox.com:8080/wileyCDA/?q=javascript#contents
分解后就是:
location.protocol:”http:”
location.href:”http://www.wrox.com”
location.host:”www.wrox.com:80”
location.post:”8080”
location.pathname:”/wileyCDA/”
location.search:”?q=javascript”
location.hash:”#contents”
位置操作:
使用 location 对象可以改变浏览器的URL。
//常用的方式有两种:
//使用assign方法
location.assign("http://www.wrox.com");
//使用href属性
location.href = "http://www.wrox.com";
当我们修改URL后,浏览器的历史记录就会增加一条新记录,因此用户点击后退按钮时,会导航到前一个页面,要想禁用这种行为,可以使用 replace() 方法
<!DOCTYPE html>
<html>
<head>
<title>You won't be able to get back here</title>
</head>
<body>
<p>Enjoy this page for a second , because you won't be coming back here.</p>
<script type="text/javascript">
setTimeout(function(){
location.replace("http://www.wrox.com/");
},1000);
</script>
</body>
</html>
与位置有关的最后一个方法是 reload()。
作用是重新加载当前页面,如给方法不传递任何参数,页面就会以最有效的方法来重新加载,也就是说,页面自上次请求以来并没有改变过,页面就会从浏览器的缓存中加载,如果强制从服务器端加载,就应该给这个方法传入一个参数 true。
//可能从浏览器缓存中加载
location.reload();
//强制从服务器端加载
location.reload(true);
10. navigator对象 :
navigator对象 现在已成为识别客户端浏览器的标准,与其他BOM对象一样,每个浏览器的 navigator对象 也有着自己的一套属性。下表列出了存在于所有浏览器的属性和方法以及支持他们的浏览器版本。
这些 navigator对象 的属性通常用于检测浏览器的类型。
检测插件 :
检测浏览器中是否安装了特定的插件是一种最常见的检测例程,对于非IE浏览器,可以使用 plugins数组 来达到这个目的,该数组中的每一项都包含下列属性。
- name : 插件的名字。
- description : 插件的描述。
- filename : 插件的文件名。
- length : 插件所处理的MIME类型数量。
//检测插件(在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"));
//检测QuickTime
alert(hasPlugin("QuickTime"));
接下来介绍检测IE中插件的方法,检测IE中的插件比较麻烦,因为IE不支持Netspace式的插件。在IE中检测插件的唯一办法就是使用专有的 ActiveXObject 类型,并尝试创建一个特定插件的实例。IE是以COM对象的方式实现插件的,而COM对象使用唯一的标识符来标识,因此,要想检查特定的插件就必须知到插件的标识符。
//检测IE中的插件
function hasIEplugin(name){
try{
new ActiveXObject(name);
return true;
}
catch(ex){
return fasle;
}
}
//检测Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash"));
//检测QuickTime
alert(hasIEPlugin("QuickTime.QuickTime"));
最后是通用的方法。
//检测所有浏览器中的Flash
//ShockwaveFlash.ShockwaveFlash是Flash的标识符
function hasFlash(){
var result = hasPlugin("Flash");
if(!result){
result = hasIEplugin("ShockwaveFlash.ShockwaveFlash");
}
return result;
}
//检测所有浏览器中的QuickTime
//QuickTime.QuickTime是Quick的标识符
function hasQuick{
var result = hasPlugin("QuickTime");
if(!result)
{
result = hasIEplugin("QuickTime.QuickTime");
}
return result;
}
//检测Flash
alert(hasFlash());
//检测QuickTime
alert(hasQuickTime());
11. screen对象 :
JavaScript有几个对象在编程中用处不大,Screen对象 就是其中一个。
Screen对象 基本上只用来表明客户端的能力。其中包括浏览器外部窗口的信息,如像素的宽度和高度等。每个浏览器中的 Screen对象 都包含着各不相同的属性,下表列出了所有属性及支持相应属性的浏览器。
12. history对象 :
history对象 保存着用户上网的历史记录。因为 history 是 window 对象的属性,因此每个浏览器窗口,每个标签页甚至每个框架,都有着自己的 history对象 与特定的 window对象 相关联。出于安全性方面考虑,开发人员无法得知用户浏览过的URL,但是借助用户访问过的页面列表,可以再不知道用户实际URL的情况下实现后退和前进。
history对象 有下列几种方法:
go() : 在用户的历史记录中任意跳转,接受一个参数,该参数表示跳转页面的一个整数值(负数表示向后跳转,正数表示向前跳转)。
也可以给该方法传递一个字符串参数,此时浏览器会跳转到包含该字符串最近的历史记录的页面上(可能前进,也可能后退),如果历史记录不包含该字符串,那么这个方法什么也不做。
//go()方法
history.go(-1); //后退一页
history.go(1); //前进一页
history.go(2); //前进两页
//还可以使用两个简写的方法来代替go()方法
history.back(); //后退一页
history.forward(); //前进一页
除了上述几个方法外,history对象 还有一个 length 属性,保存着历史记录的数量。对于加载窗口,标签页或框架中的第一个页面而言,history.length 等于0,通过测试该属性的值可以确定用户是否一开始就打开了你的页面。
//检测用户是否一开始就打开你的页面
if(history.length == 0)
{
alert("Welcome");
}