8.1 window 对象
window
对象扮演双重角色:即是访问浏览器的接口,又是 ECMAScript
规定的 Global
对象
8.1.1 全局作用域
在全局作用域上定义的变量和函数都会变成 window
对象的属性和方法
var age = 29;
function sayAge(){
alert(this.age);
}
alert(window.age); //29
sayAge(); //29
window.sayAge(); //29
全局变量和 window
属性的差别之一:全局变量不能通过 delete
操作从 window
对象中删除。因为用 var
添加的 window
属性,其 [[Configurable]]
特性被设置为 false,因此不能删除
var age = 29;
window.color = "red";
//全局变量不能删除
delete window.age;
//全局属性可以删除
delete window.color; //returns true
alert(window.age); //29
alert(window.color); //undefined
全局变量和 window
属性的差别之二:访问不存在的全局变量会报错,访问不存在的 window
属性返回 undefined
//oldValue 不存在,会报错
var newValue = oldValue;
//window.oldValue 属性不存在,仅仅返回 undefined
var newValue = window.oldValue;
8.1.2 窗口关系及框架
每个框架都有自己的 window
对象,保存在 frames
中,可以通过数值索引,索引从 0
开始,顺序是从左到右、从上到下
两个特殊的框架名称:
-
top
指向最顶层框架 -
parent
指向上层框架
8.1.3 窗口位置
screenLeft
和 screenTop
返回显示区域的坐标,除了火狐浏览器不支持,其他几种浏览器新版本都支持。
- 谷歌浏览器、IE 浏览器和
Win10
浏览器都返回0
和工具栏高度 - 火狐浏览器不支持这两个属性
screenX
和 screenY
返回窗口的坐标
- 谷歌浏览器返回和
screenLeft、
screenTop
相同的值 - 火狐和新版 IE 浏览器返回
-8
-8
- 新版 Win10 浏览器返回
0
0
下面这段代码可以在不同浏览器下都获得数值
var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;
但是因为各种浏览器的返回值各不相同,所以无法在跨浏览器的条件下取得窗口的精确坐标
moveTo
和 moveBy
方法可以将浏览器移动到准确的新位置,但是大部分新浏览器不再支持中两个方法,只有 IE 还支持
//move the window to the upper-left coordinate
window.moveTo(0,0);
//move the window down by 100 pixels
window.moveBy(0, 100);
//move the window to position (200, 300)
window.moveTo(200, 300);
//move the window left by 50 pixels
window.moveBy(-50, 0);
8.1.4 窗口大小
innerWidth
, innerHeight
在各个浏览器中均返回视口大小
outerWidth
, 和 outerHeight
- 在谷歌浏览器中还是返回视口大小
- 其他浏览器窗口大小
IE 浏览器在 IE8 之前的没有提供这几个属性。虽然无法在跨浏览器的条件下取得窗口的大小,但是可以利用下面的代码取得视口的大小
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;
}
}
改变浏览器大小
resizeTo
和 resizeBy
方法可以改变浏览器的大小,但是大部分新浏览器不再支持中两个方法,只有 IE 还支持
//resize to 100 x 100
window.resizeTo(100, 100);
//resize to 200 x 150
window.resizeBy(100, 50);
//resize to 300 x 300
window.resizeTo(300, 300);
8.1.5 导航和打开窗口
window.open
方法可以导航到一个特定的 URL
,也可以打开一个新浏览器。接受四个参数:
- URL
- 窗口目标
- 特性字符创
- 历史记录
只有第一个参数是必须的,其他都有默认值
弹出窗口
下面的代码在指定框架中打开新的页面
//等同于 <a href="http://www.wrox.com" target="topFrame"></a>
window.open("http://www.wrox.com/", "topFrame");
常用的目标窗口名称
_self
_parent
_top
_blank
第三个参数可以指定浏览器的特性,比如是否隐藏工具栏地址栏等等
设置 | 值 | 说明 |
---|---|---|
fullscreen | "yes" or "no" | 是否最大化 |
height | 数值 | |
left | 数值 | |
location | "yes" or "no" | |
menubar | "yes" or "no" | |
resizable | "yes" or "no" | |
scrollbars | "yes" or "no" | |
status | "yes" or "no" | |
toolbar | "yes" or "no" | |
top | 数值 | |
width | 数值 |
window.open 方法返回窗口对象,可以对这个对象进行操作
var wroxWin =window.open("http://www.wrox.com/","wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
//resize it
wroxWin.resizeTo(500, 500);
//move it
wroxWin.moveTo(100, 100);
close 方法可以关闭窗口对象,closed 属性可以检测窗口对象是否已经关闭
wroxWin.close();
alert(wroxWin.closed); //true
window 对象的 opener 属性保存着打开本 window 对象的那个 window 对象
var wroxWin =window.open("http://www.wrox.com/","wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
alert(wroxWin.opener == window); //true
如果将 window 对象的 opener 属性设置为 null ,则主窗口和被打开窗口分别在独立的进程中运行,两个窗口对象不再有关系
var wroxWin =window.open("http://www.wrox.com/","wroxWindow",
"height=400,width=400,top=10,left=10,resizable=yes");
wroxWin.opener = null;
安全限制
由于打开窗口可能存在安全隐患,大部分浏览器都设置了很多安全限制。
屏蔽程序
如果打开窗口被浏览器本身屏蔽,则 window.open 方法返回 null
var wroxWin = window.open("http://www.wrox.com", "_blank");
if (wroxWin == null){
alert("The popup was blocked!");
}
如果打开窗口被插件或者扩展程序屏蔽,则 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!");
}
8.1.6 间歇调用和超时调用
超时调用:setTimeout
先等待一段时间,然后将任务添加到执行队列中。需要注意的是:执行队列中的任务是根据调度执行的,不一定立即执行
回调任务可以是字符串,但是不推荐这种用法,通常还是一个回调函数
//不推荐
setTimeout("alert(‘Hello world!’) ", 1000);
//推荐用法
setTimeout(function() {
alert("Hello world!");
}, 1000);
setTimeout
方法返回一个标识符 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,clearInterval
使用这个 ID 取消间歇调用,即不再继续向执行队列中插入新的任务,但是已经插入到执行队列中的任务会继续执行。
var num = 0;
var max = 10;
var intervalId = null;
function incrementNumber() {
num++;
//如果达到条件,则取消间歇调用
if (num == max) {
clearInterval(intervalId);
alert("Done");
}
}
intervalId = setInterval(incrementNumber, 500);
上面的功能也可以利用递归超时调用来完成
var num = 0;
var max = 10;
function incrementNumber() {
num++;
//如果满足条件则进行下一次超市调用,否则退出
if (num < max) {
setTimeout(incrementNumber, 500);
} else {
alert("Done");
}
}
setTimeout(incrementNumber, 500);
超时调用在等待一定时间、向执行队列添加任务,然后退出;而间歇调用会不断地向执行队列中添加任务,想要退出必须手动调用 clearInterval
方法。因此,应该尽可能的使用超时调用,而不是间歇调用。
8.1.7 系统对话框
8.2 location 对象
location
对象是最有用的 BOM 对象之一:
- 它保存着当前加载文档的一些有用信息
- 可以进行导航
- 既是
window
的属性,又是document
的属性 - 将 URL 进行了解析,并将各部分信息保存在自己的属性中
属性名 | 例子 | 说明 |
---|---|---|
host |
"www.wrox.com:80" |
主机名加端口 |
hostname |
"www.wrox.com" |
主机名 |
href |
"http:/www.wrox.com" |
当前加载页的完整 URL,location 对象的 toString() 方法返回的也是这个值 |
hash |
"#contents" |
返回 URL 中的 hase |
pathname |
"/WileyCDA" |
返回路径或者文件名 |
port |
"8080" |
端口号 |
protocol |
"http:" |
协议字符串 |
search |
"?q=javascript" |
查询字符串 |
8.2.1 解析查询字符串参数
算法:
- 第一步:把首字母 ? 去掉
- 第二步:用 "&" 字符切分查询字符串,得到查询键值对
- 第三步:将每个键值对用 "=" 切分,得到键值
- 第四步:别忘了用 decodeURIComponent 解码
function getQueryStringArgs(){
//get query string without the initial ?
var qs = (location.search.length > 0 ? location.search.substring(1) : ""),
//object to hold data
args = {},
//get individual items
items = qs.length ? qs.split("&") : [],
item = null,
name = null,
value = null,
//used in for loop
i = 0,
len = items.length;
//assign each item onto the args object
for (i=0; i < len; i++){
item = items[i].split("=");
name = decodeURIComponent(item[0]);
value = decodeURIComponent(item[1]);
if (name.length) {
args[name] = value;
}
}
return args;
}
//assume query string of ?q=javascript&num=10
var args = getQueryStringArgs();
alert(args["q"]); //"javascript"
alert(args["num"]); //"10"
8.2.2 改变位置
location.assign 方法改变浏览器的位置
设置 window.location 和 location.href 属性也是调用 assing 方法,效果一样
location.assign("http://www.wrox.com");
window.location = "http://www.wrox.com";
location.href = "http://www.wrox.com";
设置 location 对象的其他属性也可以改变浏览器位置
//assume starting at http://www.wrox.com/WileyCDA/
//changes URL to "http://www.wrox.com/WileyCDA/#section1"
location.hash = "#section1";
//changes URL to "http://www.wrox.com/WileyCDA/?q=javascript"
location.search = "?q=javascript";
//changes URL to "http://www.yahoo.com/WileyCDA/"
location.hostname = "www.yahoo.com";
//changes URL to "http://www.yahoo.com/mydir/"
location.pathname = "mydir";
//changes URL to "http://www.yahoo.com:8080/WileyCDA/
防止产生历史记录
location.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>
重新加载页面
location.reload() 方法重新加载页面。注意:调用这个方法后,因为重新加载页面,所以之后的代码可能不会被执行。
location.reload(); //可能会从缓存加载
location.reload(true); //强制从服务器加载
8.3 navigator 对象
通过读取 navigator 对象的各种属性,可以获取浏览器的各种信息。具体用法可以查阅资料
8.3.1 检测插件
navigator 对象的 plugins 属性是个数组,其中每一项都是包含一个插件的信息
//插件检测,在 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 中的插件要使用 ActiveXObject
//检测 Internet Explorer 插件
function hasIEPlugin(name){
try {
new ActiveXObject(name);
return true;
} catch (ex){
return false;
}
}
//检测 flash
alert(hasIEPlugin(“ShockwaveFlash.ShockwaveFlash”));
//检测 quicktime
alert(hasIEPlugin(“QuickTime.QuickTime”))
综合使用上面两种方法可以检测各种浏览器的插件
//检测 flash
function hasFlash(){
var result = hasPlugin(“Flash”);
if (!result){
result = hasIEPlugin(“ShockwaveFlash.ShockwaveFlash”);
}
return result;
}
//检测 quicktime
function hasQuickTime(){
var result = hasPlugin(“QuickTime”);
if (!result){
result = hasIEPlugin(“QuickTime.QuickTime”);
}
return result;
}
//检测 flash
alert(hasFlash());
//检测 quicktime
alert(hasQuickTime());
8.3.2 注册处理程序
还不成熟,不需要了解
8.4 screen 对象
screen 可以获取用户显示器的各种信息,相关属性和方法请自行查阅资料
8.5 history 对象
每个窗口和框架都有自己的 history 对象,他是 window 的一个属性。利用 history 对象,可以在用户的浏览历史页面中跳转
按编号跳转
//go back one page
history.go(-1);
//go forward one page
history.go(1);
//go forward two pages
history.go(2);
按站点名字跳转
//go to nearest wrox.com page
history.go(“wrox.com”);
//go to nearest nczonline.net page
history.go(“nczonline.net”);
向前向后跳转
//go back one page
history.back();
//go forward one page
history.forward();
判断当前页面是否是当前窗口打开的第一个页面
if (history.length == 0){
//this is the first page in the user’s window
}