1 window 对象
window 对象有双重角色, 它既是通过 JavaScript 访问浏览器窗口的一个接口,又是 ECMAScript 规定的 Global 对象。
1.1 全局作用域与window 对象
所有在全局作用域中声明的变量、函数都会变成 window
对象的属性和方法。
var age = 29;
function sayAge(){
alert(this.age);
}
alert(window.age); //29
sayAge(); //29
window.sayAge(); //29
全局变量不能通过
delete
操作符删除,而直接在
window
对象上的定义的属性可以。
var age = 29;
window.color = "red";
//在 IE < 9 时抛出错误,在其他所有浏览器中都返回 false
delete window.age;
//在 IE < 9 时抛出错误,在其他所有浏览器中都返回 true
delete window.color; //returns true
alert(window.age); //29
alert(window.color); //undefined
尝试访问未声明的变量会抛出错误,但是通过查询 window 对象,可以知道某个可能未声明的变量是否存在。
//这里会抛出错误,因为 oldValue 未定义
var newValue = oldValue;
//这里不会抛出错误,因为这是一次属性查询
//newValue 的值是 undefined
var newValue = window.oldValue;
1.2 窗口关系及框架
1.2.1 框架
每个框架都拥有自己的 window 对象,并且保存在 frames 集合中。每个 window 对象都有一个 name 属性,其中包含框架的名称。
<html>
<head>
<title>Frameset Example</title>
</head>
<frameset rows="160,*">
<frame src="frame.htm" name="topFrame">
<frameset cols="50%,50%">
<frame src="anotherframe.htm" name="leftFrame">
<frame src="yetanotherframe.htm" name="rightFrame">
</frameset>
</frameset>
</html>
- top 对象始终指向最高(最外)层的框架,也就是浏览器窗口。
- window 对象指向的都是某个框架的特定实例,而非最高层的框架。
- self对象 ,它始终指向 window。
- parent(父)对象始终指向当前框架的直接上层框架。所有这些对象都是 window 对象的属性,可以通过 window.parent、window.top 等形式来访问。
<html>
<head>
<title>Frameset Example</title>
</head>
<frameset rows="100,*">
<frame src="frame.htm" name="topFrame">
<frameset cols="50%,50%">
<frame src="anotherframe.htm" name="leftFrame">
<!--框架集-->
<frame src="anotherframeset.htm" name="rightFrame">
</frameset>
</frameset>
</html>
<!--框架集-->
<html>
<head>
<title>Frameset Example</title>
</head>
<frameset cols="50%,50%">
<frame src="red.htm" name="redFrame">
<frame src="blue.htm" name="blueFrame">
</frameset>
</html>
如果代码位于 redFrame(或
blueFrame
)中,那么
parent
对象指向的就是
rightFrame。
如果代码位于 topFrame 中,则
parent
指向的是
top。
1.2.2 窗口位置
使用下列代码可以跨浏览器取得窗口左边和上边的位置。最终结果,就是无法在跨浏览器的条件下取得窗口左边和上边的精确坐标值。
var leftPos = (typeof window.screenLeft == "number") ?
window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ?
window.screenTop : window.screenY;
moveTo()
接收的是新位置的
x
和
y
坐标值,而
moveBy()
接收的是在水平和垂直方向上移动的像素数。
//将窗口移动到屏幕左上角
window.moveTo(0,0);
//将窗向下移动 100 像素
window.moveBy(0,100);
//将窗口移动到(200,300)
window.moveTo(200,300);
//将窗口向左移动 50 像素
window.moveBy(-50,0);
1.2.3 窗口大小
浏览器取得页面视口的大小
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.innerWidth
和
window.innerHeight
保存着可见视口,也就是屏幕上可见页面区域的大小。
document.documentElement 度量的是布局视口,即渲染后页面的实际大
小(与可见视口不同,可见视口只是整个页面中的一小部分)。
resizeTo()接收浏览器窗口的新宽度和新高度,而
resizeBy()接收新窗口与原窗口的宽度和高度之差。
//调整到 100×100
window.resizeTo(100, 100);
//调整到 200×150
window.resizeBy(100, 50);
//调整到 300×300
window.resizeTo(300, 300);
1.2.4 导航和打开窗口
使用
window.open()
方法既可以导航到一个特定的
URL
,也可以打开一个新的浏览器窗口。这个方法可以接收 4
个参数:要加载的
URL、窗口目标、一个特性字符串以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。返回一个指向新窗口的引用。
//等同于< a href="http://www.wrox.com" target="topFrame"></a>
window.open("http://www.wrox.com/", "topFrame");
如果有一个名叫
"topFrame"
的窗口或者框架,就会在该窗口或框架加载这个
URL
;否则,就会创建一个新窗口并将其命名为"topFrame"
。
1.
弹出窗口
调用
close()
方法还可以关闭新打开的窗口。
window.open("http://www.wrox.com/","wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
//调整大小
wroxWin.resizeTo(500,500);
//移动位置
wroxWin.moveTo(100,100);
wroxWin.close();
新创建的
window
对象有一个
opener
属性,其中保存着打开它的原始窗口对象。将 opener
属性设置为
null
就是告诉浏览器新创建的标签页不需要与打开它的标签页通信,因此可以在独立的进程中运行。标签页之间的联系一旦切断,将没有办法恢复。
var wroxWin = window.open("http://www.wrox.com/","wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
alert(wroxWin.opener == window); //true
2.
安全限制
广告商在网上使用弹出窗口达到了肆无忌惮的程度。只能通过单击或者击键来打开弹出窗口。
3.
弹出窗口屏蔽程序
如果是浏览器内置的屏蔽程序阻止的弹出窗口,那么 window.open()
很可能会返回
null
。
如果是浏览器扩展或其他程序阻止的弹出窗口,那么
window.open()
通常会抛出一个错误。
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!");
}
1.3 间歇调用和超时调用
超时调用需要使用 window
对象的
setTimeout()
方法,它接受两个参数:要执行的代码和以毫秒表示的时间。setTimeout()
的第二个参数告诉 JavaScript 再过多长时间把当前任务添加到队列中。但经过该时间后指定的代码不一定会执行,些任务会按照将它们添加到队列的顺序执行。
要取消尚未执行的超时调用计划,可以调用clearTimeout()方法并将相应的超时调用 ID 作为参数传递给它。
//设置超时调用
var timeoutId = setTimeout(function() {
alert("Hello world!");
}, 1000);
//注意:把它取消
clearTimeout(timeoutId);
设置间歇调用的方法是
setInterval()
,它接受的参数与
setTimeout()
相同。
要取消尚未执行的间歇调用,可以使用
clearInterval()
方法并传入相应的间歇调用
ID
。
//最好不要使用间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动。
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); //没有必要跟踪超时调用 ID,因为每次执行代码之后,如果不再设置另一次超时调用,调用就会自行停止
} else {
alert("Done");
}
}
setTimeout(incrementNumber, 500);
1.4 系统对话框
alert()、confirm()和 prompt()通过这几个方法打开的对话框都是同步和模态的。也就是说,显示这些对话框的时候代码会停止执行,而关掉这些对话框后代码又会恢复执行。
alert()方法,这个方法接受一个字符串并将其显示给用户。其中包含指定的文本和一个
OK
(“确定”)按钮。
用
confirm()方法,除了显示 OK 按钮外,还会显示一个 Cancel(“取消”)按钮。
返回的布尔值:true 表示单击了 OK,false 表示单击了 Cancel 或单击了右上角的 X 按钮。
if (confirm("Are you sure?")) {
alert("I'm so glad you're sure! ");
} else {
alert("I'm sorry to hear you're not sure. ");
}
prompt()方法接受两个参数:要显示给用户的文本提示和文本输入域的默认值(可以是一个空字符串)。如果用户单击了 OK 按钮,则 prompt()
返回文本输入域的值;如果用户单击了 Cancel 或没有单击OK 而是通过其他方式关闭了对话框,则该方法返回 null。
var result = prompt("What is your name? ", "");
if (result !== null) {
alert("Welcome, " + result);
}
find()和 print()
方法“查找”和“打印”。这两个对话框都是异步显示的,能够将控制权立即交还给脚本。
//显示“打印”对话框
window.print();
//显示“查找”对话框
window.find();
2 location 对象
它提供了与当前窗口中加载的文档有关的信息,还提供了一 些导航功能。
2.1 查询字符串参数
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("="); //获取k-v,用=切分
name = decodeURIComponent(item[0]); //再使用 decodeURIComponent()分别解码 name 和 value(因为查询字符串应该是被编码过的)
value = decodeURIComponent(item[1]);
if (name.length) {
args[name] = value;
}
}
return args;
}
2.2 位置操作
使用 location 对象可以通过很多方式来改变浏览器的位置。当通过下述任何一种方式修改 URL 之后,浏览器的历史记录中就会生成一条新记录,因此用户通过单击“后退”按钮都会导航到前一个页面。
- 最常用的方式,就是使用 assign()方法并为其传递一个 URL。
- 通过将hash、 search、hostname、pathname 和 port 属性设置为新值来改变 URL。每次修改 location 的属性(hash 除外),页面都会以新 URL 重新加载。
location.assign("http://www.wrox.com");
//等价于
window.location = "http://www.wrox.com";
location.href = "http://www.wrox.com";
//假设初始 URL 为 http://www.wrox.com/WileyCDA/
//将 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 = "www.yahoo.com";
//将 URL 修改为"http://www.yahoo.com/mydir/"
location.pathname = "mydir";
//将 URL 修改为"http://www.yahoo.com:8080/WileyCDA/"
location.port = 8080;
- 调用 replace()方法之后,用户不能回到前一个页面。这个方法只接受一个参数,即要导航到的 URL。
location.replace("http://www.wrox.com/");
- reload(),作用是重新加载当前显示的页面。不传递任何参数,也就是说,如果页面自上次请求以来并没有改 变过,页面就会从浏览器缓存中重新加载。如果要强制从服务器重新加载,则需要为该方法传递参数 true。
位于 reload()
调用之后的代码可能会也可能不会执行,这要取决于网络延迟或系统资源等因素。 为此,最好将 reload()
放在代码的最后一行。
location.reload(); //重新加载(有可能从缓存中加载)
location.reload(true); //重新加载(从服务器重新加载)
3 navigator 对象
navigator 对象的属性通常用于检测显示网页的浏览器类型。
3.1 检测插件
在检测插件时, 需要像下面这样循环迭代每个插件并将插件的 name
与给定的名字进行比较。
//检测插件(在 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){ //插件的 name
return true;
}
}
return false;
}
//检测 Flash
alert(hasPlugin("Flash"));
//检测 QuickTime
alert(hasPlugin("QuickTime"));
IE
是以
COM
对象的方式实现插 件的,而 COM
对象使用唯一标识符来标识。
//检测 IE 中的插件
function hasIEPlugin(name){
try {
new ActiveXObject(name); //在 try-catch 语句中进行实例化
return true;
} catch (ex){
return false;
}
}
//检测 Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash"));
//检测 QuickTime
alert(hasIEPlugin("QuickTime.QuickTime"));
鉴于检测这两种插件的方法差别太大,因此典型的做法是针对每个插件分别创建检测函数。
//检测所有浏览器中的 QuickTime
function hasQuickTime(){
var result = hasPlugin("QuickTime");
if (!result){
result = hasIEPlugin("QuickTime.QuickTime");
}
return result;
}
//检测 QuickTime
alert(hasQuickTime());
plugins
集合有一个名叫
refresh()
的方法,用于刷新
plugins
以反映最新安装的插件。这个方法接收一个参数:表示是否应该重新加载页面的一个布尔值。
3.2 注册处理程序
registerContentHandler()
方法接收三个参数:要处理的
MIME
类型、可以处理该
MIME类型的页面的 URL
以及应用程序的名称。
navigator.registerContentHandler("application/rss+xml",
"http://www.somereader.com?feed=%s", "Some Reader");//当下一次请求 RSS 源时,浏览器就会打开指定的 URL,而相应的Web 应用程序将以适当方式来处理该请求
registerProtocolHandler()
方法,它也接收三个参数:要处理的协议(例如,mailto
或
ftp
)、处理该协议的页面的
URL
和应用程序的名称。
navigator.registerProtocolHandler("mailto",
"http://www.somemailclient.com?cmd=%s", "Some Mail Client");//注册了一个 mailto 协议的处理程序,该程序指向一个基于 Web 的电子邮件客户端。
4 screen 对象
调整浏览器窗口大小,使其占据屏幕的可用空间。而
Android
设备则会相应调用
screen.width
和
screen.height
的值。
window.resizeTo(screen.availWidth, screen.availHeight);
5 history 对象
history 对象保存着用户上网的历史记录。
go()方法可以在用户的历史记录中任意跳转,接受一个
参数, 表示向后或向前跳转的页面数的一个
整数值。
也可以给 go()
方法传递一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置——可能后退,也可能前进,具体要看哪个位置最近。
//后退一页
history.go(-1);
//前进一页
history.go(1);
//跳转到最近的 wrox.com 页面
history.go("wrox.com");
用两个简写方法
back()和 forward()
来代替 go(),模仿浏览器的“后退”和“前进”按钮。
//后退一页
history.back();
//前进一页
history.forward();
history
对象还有一个
length
属性,保存着历史记录的数量。
if (history.length == 0){
//这应该是用户打开窗口后的第一个页面
}