BOM——《JavaScript高级程序设计》笔记
八、BOM
8.1 window对象
window是BOM的核心,表示浏览器的一个实例,是访问浏览器窗口的一个接口,也是ECMAScript规定的Global对象。
8.1.1 全局作用域
在全局作用域中声明的所变量、函数都是window对象的属性和方法
定义全局变量 与 在window对象上直接定义属性 的差别:
全局变量无法使用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
【在IE9以下,使用delete删除window的属性都会抛出错误!】
访问未声明的变量会抛出错误。但通过window对象可知道某个未声明的对象是否存在。
var newValue = window.oldValue; //newValue被赋值undefined。这里不会抛出错误,因为这是一次属性查询!
8.1.2 窗口关系 及 框架
@frames集合:每个框架都有自己的window对象,保存在frames集合中,可用数值索引或框架名访问对应的window对象。
每个window都有一个name属性包含框架名称。除非最高层窗口时通过window.open()打开的,否则该name属性不包含任何值。
@top对象:它始终指向最高(最外)层框架,即浏览器窗口。可通过它访问另一个框架。
@parent对象:(父)对象,始终指向当前框架的直接上层框架。
当没有框架时,parent = top = window 。
@self对象:始终指向window,可以跟window对象互换使用。【引用self对象只是为了与top和parent对应,不包含其他值】
@每个框架都有一套自己的构造函数,这些函数一一对应,但不相等。如,top.Object不等于top.frames[0].Object。
8.1.3 窗口位置【无法跨浏览器取得精确值】
screenLeft/screenTop (IE、Chrome 、Safari和 Opera)
screenX/screenY (FireFox、Chrome 和 Safari)
@IE 和 Opera中,screenLeft/screenTop返回指定框架 相对屏幕的坐标。
@FireFox、Chrome 和 Safari中,screenLeft或screenX始终返回整个浏览器 相对屏幕的坐标。
moveTo():接收窗口新位置的坐标。
moveBy():接收窗口水平和垂直移动的像素数
@这两种方法都可能被浏览器禁用,却不适用于框架。
8.1.4 窗口大小
@在IE9+、FF、Safari 和 Opera中,innerWidth/innerHeight指视口大小,outerWidth/outerHeight指浏览器窗口大小。
@在Chrome中,innerWidth/innerHeight 和 outerWidth/outerHeight 都是指视口大小。
@在IE6 的标准模式中,document.documentElement.clientWidth/...中保存了页面视口的信息。
在混杂模式中,则是document.body.clientWidth/...中保存了视口的信息。
获取页面视口大小:
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;
}
}
8.1.5 导航 和 打开窗口
① window.open()方法:四个参数,要加载的URL、窗口目标、特殊性字符串 及 一个布尔值。
@特殊性字符串:在不打开新窗口时,被忽略。menubar、status、toolbar、resizeble、location、left/top、width/height(最新值100)。
@布尔值:在不打开新窗口时可用,表示新页面是否取代浏览器历史记录中当前加载的页面。
@该方法会返回一个指向新窗口的引用,一些默认禁止修改主浏览器窗口大小和位置的,但允许通过window.open()调整窗口大小和位置。
② close()方法可关闭新打开的窗口。
@虽然没有用户的允许无法关闭主浏览器,但可以通过top.close()在不经用户允许中关闭弹出窗口。
@窗口关闭后,窗口引用依然还在,但只有用于检测是否关闭的closed属性(返回布尔值)。
③ opener属性:新创建的window对象有一个opener属性,保存着打开它的原始窗口对象。
@该属性只在弹出窗口的最外层window对象(top)中有定义,指向调用window.open()的窗口或框架。
@虽然弹出窗口有一个指针指向打开它的原始窗口,但原始窗口并没有这样的指针指向弹出窗口,原始窗口不跟踪记录他们打开的弹出窗口。
@IE和Chrome会在独立进程中运行每个标签页,若两个window对象需要通信,就不能运行在独立的进程中。
将opener设为null即告诉浏览器新创建的标签页不需与打开它的标签页通信,因此才能在独立的进程中运行,标签页之间的联系若切断,无法恢复。
8.1.6 间歇调用、超时调用
JavaScript是单线程语言,但能通过设置超时值和间歇时间值来调度代码在特定的时刻执行。
超时调用 setTimeout()
setTimeout("alert('Hello world!') ", 1000);
setTimeout(function() {
alert("Hello world!");
}, 1000);
@该方法的第一个参数可以是一个字符串或一个函数。由于传递字符串可能导致性能损失,故不建议使用字符串。
@由于JavaScript是单线程序的解析器,一定时间内只能执行一段代码。为了控制要执行的代码,就有一个JavaScript任务队列。
第二个参数指定过多长时间吧当前任务添加到队列中。若队列不为空,要等到前面的代码执行完后,才会执行setTimeout()指定的代码。
@调用setTimeout()后,该方法会返回一个数值ID,表示超时调用。该超时调用ID是计划执行代码的唯一标识符。
@要取消未执行的超时调用时,可调用clearTimeout()方法,将相应的超时调用ID作为参数传递给它。
@超时调用的代码都是在全局作用域中在执行的,因此函数中的this对象,在非严格模式下指向window对象,在严格模式下是undefined。
间歇调用 setInterval()
@调用该方法同样会返回一个间歇调用ID,并通过clearInterval()方法取消间歇调用。
var num = 0;
var max = 100;
function incrementNumber() {
num++;
//在执行次数不够指定次数时,重复超时调用
if (num < max) {
setTimeout(incrementNumber, 500);
} else {
alert("Done");
}
}
setTimeout(incrementNumber, 500);
通常,使用超时调用来模拟间歇调用是一种最佳方案。
8.1.7 系统对话框
浏览器通过alert()、comfirm() 和 prompt()调用系统对话框。通过这些方法打开的对话框都是同步和模态的,显示时代码会停止执行。
系统对话框与浏览器中显示的网页无关,不包含HTML。
if (confirm("Are you sure?")) {
alert("I'm so glad you're sure! ");
} else {
alert("I'm sorry to hear you're not sure. ");
}
@这种模式常在用户想要执行删除操作时使用。
var result = prompt("What is your name? ", "文本框默认值");
if (result !== null) {
alert("Welcome, " + result);
}
@prompt()返回文本域中的值,或返回null。
还可通过JavaScript打开“查找”和“打印”对话框:window.print() 和 window.find()。
8.2 location对象
提供当前窗口加载的文档信息。
@location是一个特别的对象,它既是window对象的属性,也是document对象的属性。window.location和document.location引用同个对象。
@location将URL解析成独立的片段:
href:返回完整URL。location对象的toString()方法也返回该值
protocol:返回页面的协议。常为http:或https:
hostname:返回不带端号的服务器名称
host:若有,返回带端号的服务器名称
port:返回URL中指定的端号,无则返回空字符串
pathname:返回目录和/或文件名
search:返回查询字符串
hash:返回散列,无则返回空字符串
8.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("=");
name = decodeURIComponent(item[0]);
value = decodeURIComponent(item[1]);
if (name.length){
args[name] = value;
}
}
return args;
}
//假设查询字符串为?q=javascript&num=10
var args = getQueryStringArgs();
alert(args["q"]); //"javascript"
alert(args["num"]); //"10"
@由于查询字符串应该是被编码过的,所以要用decodeURIComponent()对其进行解码
8.2.2 位置操作
通过location对象改变浏览器的位置 最常见的方式是给assign()方法传递一个URL:
location.assign("http://www.site.com"); 执行后立即打开新URl并在浏览器的历史记录中生成一条记录。
@将location.href或window.location设置为一个URl值,也会调用assign()方法。
修改location上述的属性(除了hash),页面都会以新URL重新加载,历史记录中都会生一条新记录。
@在IE8+等浏览器中,修改hash值会在历史记录中生成新记录,
@在IE7-的浏览器中,用户单击“后退”和“前进”后 不会更新hash属性,只有在用户点击包含hash的URL时才会被更新。
当上述的属性如何一种属性被修改时,历史记录中都会生成一条新记录,用户可以使用“后退”和“前进”导航到记录的页面。
@使用replace()方法能禁止此行为。
setTimeout(function () {
location.replace("http://www.wrox.com/");
}, 1000);
reload()方法,重新加载当前显示的页面。
@若无传递参数,页面会以最有效的方式重新加载。即若页面自上传加载后无修改时,页面将从缓存中重新加载。
@传递true参数,能强制页面从服务器重新加载。
8.3 navigator对象
此对象常用于识别客户端浏览器 或检测插件。
8.4 screen对象
基本上用来表明客户端的能力。包括浏览器窗口外部的显示器信息。每个浏览器的screen对象都包含不相同的属性。
设置全屏:【很多浏览器都禁止设置浏览器窗口大小】
window.resize(screen.availWidth,screen.availHeight);
8.5 history对象
保存用户上网的历史记录,从窗口打开的那一刻算起。
处于安全考虑,开发人员无法获取用户浏览过的URL,但借由用户访问过的页面列表。同样可以在不知道实际URl的情况下实现后台和前进。
go()方法,可在用户的历史记录中任意跳转。
@传入正整数向前跳转,传入负整数向后跳转。history.go(2); //向前跳转两页
@转入字符串参数时,浏览器会跳转到历史记录中包含该字符串的(最近的位置)第一个位置(前进或后退)。history.go("site.net");
@back()和forward()能够实现后退和前进。
history对象有一个length属性,保存着所有 向后或向前的历史记录 的数量。
@对于加载到窗口、标签页 或 框架的第一个页面,history.length等于0。【可以此判断用户是否一开始就打开你的页面】
history对象虽然不常用,但在创建自定义“后退”和“前进”按钮,和检测当前页是不是历史记录中的第一个页面时,必须用到它。