第8 章 BOM
8.1.1 全局作用域
全局变量不能通过delete操作符删除,而直接在window对象上的定义的属性可以:
例如:
var age = 29;
windows.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;
8.1.2 窗口关系及框架
如果页面中包含框架,则每个框架都拥有自己的window 对象,并且保存在frames 集合中。在frames集合中,可以通过数值索引(从0 开始,从左至右,从上到下)或者框架名称来访问相应的window 对象。
每个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>
以上代码创建了一个框架集,其中一个框架居上,两个框架居下。对这个例子而言,可以通过
window.frames[0]或者window.frames[“topFrame”]来引用上方的框架。不过,恐怕你最好使用
top 而非window 来引用这些框架(例如,通过top.frames[0])。
我们知道,top 对象始终指向最高(最外)层的框架,也就是浏览器窗口。使用它可以确保在一个
框架中正确地访问另一个框架.
框架中window 对象:
window.frames[0]或者window.frames[“topFrame”]
在每个框架中定义的全局变量会自动成为 框架中window 对象的属性.
==========================================================
8.1.3 窗口位置
用来确定和修改window 对象位置的属性和方法有很多
提供相同的窗口位置信息的属性
window.screenLeft : window.screenX;
window.screenTop : window.screenY;
//将窗口精确地移动到一个新位置的方法
window.moveTo(0,0);
window.moveBy(0,100);
这两个方法都不适用于框架,只能对最外层的window 对象使用
8.1.4 窗口大小
使用resizeTo()和resizeBy()方法可以调整浏览器窗口的大小。
8.1.5 导航和打开窗口
使用window.open()方法既可以导航到一个特定的URL,也可以打开一个新的浏览器窗口。
8.1.6 间歇调用和超时调用
超时调用需要使用window 对象的setTimeout()方法,在指定的时间过后执行代码。
//不建议传递字符串!
setTimeout("alert('Hello world!') ", 1000);
//推荐的调用方式
setTimeout( function() {
alert("Hello world!");
}, 1000 );
第二个参数是一个表示等待多长时间的毫秒数,但经过该时间后指定的代码不一定会执行。
JavaScript 是一个单线程序的解释器,因此一定时间内只能执行一段代码。为了控制要执行的代码,就有一个JavaScript 任务队列。这些任务会按照将它们添加到队列的顺序执行。setTimeout()的第二个参数告诉JavaScript 再过多长时间把当前任务添加到队列中。如果队列是空的,那么添加的代码会立即执行;如果队列不是空的,那么它就要等前面的代码执行完了以后再执行。
调用setTimeout()之后,该方法会返回一个数值ID,表示超时调用。这个超时调用ID 是计划执
行代码的唯一标识符,可以通过它来取消超时调用。要取消尚未执行的超时调用计划,可以调用
clearTimeout()方法并将相应的超时调用ID 作为参数传递给它,如下所示。
//设置超时调用
var timeoutId = setTimeout(function() {
alert("Hello world!");
}, 1000);
//注意:把它取消
clearTimeout(timeoutId);
设置间歇调用的方法是setInterval()
//不建议传递字符串!
setInterval ("alert('Hello world!') ", 10000);
//推荐的调用方式
setInterval (function() {
alert("Hello world!");
}, 10000);
调用setInterval()方法同样也会返回一个间歇调用ID,该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);
//很少使用真正的间歇调用,原因是后一个间歇调用可能会在前一个间歇调用结束之前启动。
可以使用超时调用 来模仿间歇调用。
8.1.7 系统对话框
浏览器通过alert()、confirm()和prompt()方法可以调用系统对话框向用户显示消息
8.2 location 对象
它既是window 对象的属性,也是document 对象的属性,window.location 和document.location 引用的是同一个对象。
location 对象的用处不只表现在它保存着当前文档的信息,还表现在它将URL 解析为独立的片段,让开发人员可以通过不同的属性访问这些片段。
8.2.1 查询字符串参数
//假设查询字符串是?q=javascript&num=10
var args = getQueryStringArgs();
//此函数去?号, 去?号的字符串.split("&")得到每一项字符串,
//然后用得到的每一项字符串.split("=") 分解每一项, 得到成对的Key Value
alert(args["q"]); //"javascript"
alert(args["num"]); //"10"
8.2.2 位置操作
location.assign("http://www.wrox.com");
//例如,下列两行代码与显式调用assign()方法的效果完全一样。
另外,修改location 对象的其他属性也可以改变当前加载的页面。下面的例子展示了通过将hash、
search、hostname、pathname 和port 属性设置为新值来改变URL。
//假设初始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;
每次修改location 的属性(hash 除外),页面都会以新URL 重新加载。
8.3 navigator 对象
navigator 对象,现在已经成为识别客户端浏览器的事实标准。
8.3.1 检测插件
第9 章客户端检测
9.1 能力检测
能力检测的目标不是识别特定的浏览器,而是识别浏览器的能力。
function getElement(id){
if (document.getElementById){
return document.getElementById(id);
} else if (document.all){
return document.all[id];
} else {
throw new Error("No way to retrieve element!");
}
}
要理解能力检测,首先必须理解两个重要的概念。如前所述,第一个概念就是先检测达成目的的最常用的特性。对前面的例子来说,就是要先检测document.getElementById(),后检document.all。
先检测最常用的特性可以保证代码最优化,因为在多数情况下都可以避免测试多个条件。
第二个重要的概念就是必须测试实际要用到的特性。一个特性存在,不一定意味着另一个特性也存
在。
怪癖检测 用户代理检测略:
在决定使用哪种客户端检测方法时,一般应优先考虑使用能力检测。怪癖检测是确定应该如何处理
代码的第二选择。而用户代理检测则是客户端检测的最后一种方案,因为这种方法对用户代理字符串具有很强的依赖性。