BOM
浏览器对象模型。
window对象
BOM的核心对象,表示浏览器的一个实例。
全局作用域
在网页中定义的任何一个对象、变量和函数,都以window作为其Global对象。
抛开全局变量会成为window对象的属性不谈。定义全局变量与在window对象上直接定义属性还是有一点差别:全局变量不能通过delete操作符删除,而直接在window对象上定义的属性可以。
var age = 20;
window.name = "yang";
delete window.age; // 在IE < 9时抛出错误,其他浏览器中返回false
delete window.name; // 在IE < 9时抛出错误,其他浏览器中返回true
尝试访问未声明的变量会抛出错误,但是通过查询window对象,可以知道某个可能未声明的变量是否存在。
var newValue = oldValue; // 这里会抛出错误,因为oldValue未定义
var newValue = window.oldValue; // 这里不会抛出错误,因为这是一次属性查询,newValue的值是undefined
窗口关系及框架
如果页面中包含框架frame,则每个frame都拥有自己的window对象,并且保存在frames集合中。
在最高层窗口中访问:
top.frames[0]; | top.frames["frameName"];
window.frames[0]; | window.frames["frameName"];
frames[0]; | frames["frameName"];
top对象始终指向最高(最外)层的框架,也就是浏览器窗口。使用它可以确保在一个框架中正确地访问另一个框架。因为对于在一个框架中编写的任何代码来说,其中的window对象指向的都是那个frame的特定实例,而非最高层的框架。
parent对象始终指向当前frame的直接上层frame.
self对象始终指向window对象,实际上,self和window对象可以互换使用。
所有这些对象(top,parent,self)都是window对象的属性,可以通过window.top等形式访问。
窗口位置
// 窗口相对于屏幕左边的位置
var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX;
// 窗口相对于屏幕上边的位置
var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;
不同浏览器中返回的topPos值可能不太相同,导致在跨浏览器的条件下取得窗口左边和上边的精确坐标值。
移动窗口位置
移动窗口位置(这两个方法可能会被浏览器禁用,且不适用于框架,只能对最外层的window对象使用):
moveTo(newX,newY); // 接收的参数是新位置的x和y坐标值。
moveBy(disX,disY); // 接收的参数是在水平和垂直方向上移动的像素数。
窗口大小
在IE9+,Safari,Firefox中,outerWidth和outerHeight返回浏览器窗口本身的尺寸(无论是从最外层的window对象还是从某个frame访问)。
在Opera中,outerWidth和outerHeight的值表示页面视图容器(Opera中单个标签页对应的浏览器窗口)的大小。innerWidth和innerHeight表示该容器中页面视图区的大小(减去边框宽度)。
在Chrome中,outerWidth和outerHeight、innerWidth和innerHeight返回相同的值,即视口(viewport)大小而非浏览器窗口的大小。
即无法准确确定浏览器窗口本身的大小(不同浏览器中不同),但是可以取得页面视口的大小:
var pageWidth = window.innerWidth,
pageHeight = window.innerHeight;
if(typeof pageWidth != "number"){
if(document.compatMode == "CSS1Compat"){ // 判断页面是否处于标准模式
pageWidth = document.documentElement.clientWidth;
pageHeight = document.documentElement.clientHeight;
} else { // IE6 混杂模式
pageWidth = document.body.clientWidth;
pageHeight = document.body.clientWidth;
}
}
调整浏览器窗口大小
调整浏览器窗口大小(有可能被浏览器禁用,且不适用于框架,只能对最外层的window对象使用):
resizeTo(newWidth.newHeight); // 接收的参数为浏览器窗口大小的新宽度和新高度。
resizeBy(w,h); // 接收的参数为新窗口与原窗口的宽度和高度之差。
导航和打开窗口
使用window.open()方法既可以导航到一个特定的URL,也可以打开一个新的浏览器窗口。这个方法可以接收4个参数:要加载的URL、窗口目标、一个特性字符串以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。
var newWindow = window.open("www.baidu.com", "newWindow", "height=400,width=400,top=10,left=10,resizable=yes");
newWindow.close(); // 这个方法仅适用于通过window.open()方法打开的弹出窗口。
top.close(); // 弹出窗口在不经用户允许的情况下自己关闭自己。
新创建的window对象有一个opener属性,其中保存着打开它的原始窗口对象。这个属性只在弹出窗口中的最外层的window对象(top)中有定义。
newWindow.opener = window; // true
检测弹出窗口屏蔽程序
检测用window.open()打开的弹出窗口是不是被屏蔽了,并不会阻止浏览器显示与被屏蔽的弹出窗口有关的信息。
var blocked = false;
try{
var newWindow = window.open("","_blank");
if(newWindow == null){ // 是浏览器内置的屏蔽程序阻止的弹出窗口
blocked = true;
}
} catch(e) { // 抛出错误 是浏览器内扩展或其他程序阻止的弹出窗口
blocked = true;
}
if(blocked){
alert("The popup was blocked!");
}
间歇调用和超时调用
- 超时调用: 该函数可以让某个函数在经过一段预定的时间之后才开始执行。只执行一次。
/**
* arg0: 要执行的函数的名字的字符串
* arg1: 以毫秒为单位,设定了需要经过多长时间后才开始执行arg0所给出的函数
*/
var timer = setTimeout("function()" | function,interval);
// 取消某个正在排队等待执行的函数
clearTimeout(timer);
- 间歇调用: 指定之间间隔,重复执行
var timer = setInterval("function()" | function,interval);
clearInterval(timer);
系统对话框
- 浏览器通过alert()、confirm()、prompt()方法可以调用系统对话框向用户显示信息。
- 系统对话框与在浏览器中显示的网页没有关系,也不包含HTML。他们的外观由操作系统及(或)浏览器设置决定,而不是由CSS决定。
- 显示这些对话框的时候代码会停止执行,而关掉这些对话框后又会恢复执行。
alert();
alert()生成“警告”对话框,向用户显示一些他们无法控制的信息,例如错误消息。用户只能在看完消息后关闭对话框。
confirm();
confirm()生成“确认”对话框,有两个按钮(OK,Cancel),点击两个按钮返回布尔值可以让用户决定是否执行给定的操作。
if(confirm("Are you sure?")){
alert("OK");
}else {
alert("Cancel");
}
prompt();
prompt()生成“提示”对话框,用于提示用户输入一些文本。提示框中除了“OK”和“Cancel”按钮之外,还会显示一个文本输入域,以供用户在其中输入内容。
prompt()方法接受两个参数:要显示给用户的文本提示和文本输入域的默认值(可以是一个空字符串)。
prompt("What's your name?","YangZhaobin");
如果用户点击“OK”返回文本输入域的值;如果用户点击“Cancel”或没有单击“OK”而是通过其他方式关闭了提示框,则该方法返回null。
location对象
- location对象提供了与当前窗口中加载的文档有关的信息,还提供了一些导航功能。
- location对象既是window对象的属性,也是document对象的属性。
- location对象的用户不仅仅表现在它保存着当前文档的信息,还表现在它将URL解析为独立的片段,让开发人员可以通过不同的属性访问这些片段。
URL解析
属性名 | 例子 | 说明 |
---|---|---|
hash | “#content” | 返回URL中的hash(#号后跟0或多个字符),如果URL中不包含散列,则返回空字符串 |
host | “www.baidu.com:8080” | 返回服务器名称和端口号(如果有) |
hostname | “www.baidu.com” | 返回不带端口号的服务器名称 |
href | “http:/www.baidu.com” | 返回当前加载页面的完整URL。location对象的toString()方法也返回这个值 |
pathname | “/file” | 返回URL中的目录和(或)文件名 |
port | “8080” | 返回URL中指定的端口号。如果URL中不包含端口号,则这个属性返回空字符串 |
protocol | “http:” | 返回页面使用的协议。通常是http:或者https: |
search | “?q=javascript” | 返回URL的查询字符串。这个字符串以问号开头 |
查询字符串参数
/**
* 解析查询字符串
* return: 包含所有参数的一个对象
*/
function getQueryStringArgs(){
// 取得查询字符串并去掉开头的问号
var qs = (location.search.length > 0 ? location.search.substring(1) : ""),
// 保存数据的对象
args = {};
if(qs != ""){
// 取得每一项
items = qs.length ? qs.split("&") : [],
item = null,
name = null,
value = null,
for(i = 0;i < items.length;i++){
item = items[i].split("=");
name = decodeURIComponent(item[0]);
value = decodeURIComponent(item[1]);
if(name.length){
args[name] = value;
}
}
}
return args;
}
位置操作
使用location对象可以通过很多方式来改变浏览器的位置。
使用assign()方法可以立即打开新URL并在浏览器的历史记录中生成一条记录。
location.assign("http://www.baidu.com");
等效方法:
location.href = "http://www.baidu.com"; // 最常用
window.location = "http://www.baidu.com";
修改location对象的其他属性值也可以改变当前加载的页面(hash,search,hostname,pathname,port)。
使用上述任何一种方法都可以在浏览器的历史记录中生成一条记录,通过点击后退按钮可以返回前一个页面。要急用这种行为,可以使用replace()方法。 这个方法只接受一个参数,即要导航到的URL。即在调用该方法之后,无法在浏览器的历史记录中生成一条记录,用户不能回到前一个页面。
reload()方法的作用是重新加载当前显示的页面。
如果调用reload()方法是不传递任何参数,页面就会以最有效的方式重新加载,也就是说,如果页面自上次请求以来并没有改变过,页面就会从浏览器缓存中重新加载。如果要强制从服务器重新加载,则要传递参数true。
需要注意的是,位于reload()之后的代码可能会也可能不会执行,这要取决于网络延迟或系统资源等因素。为此,最好将reload()放在代码的最后一行。
navigator对象
navigator对象的属性通常用于检测显示网页的浏览器类型。
检测插件
/**
* 检测浏览器中是否安装了特定的插件 (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;
}
/**
* 检测IE浏览器中是否安装了特定的插件
* 参数为插件的COM标识符
*/
function hasIEPlugin(name){
try{
new ActiveXObject(name);
return true;
}catch(e){
return false;
}
}
alert(hasPlugin("Flash")); // 检测浏览器是否有Flash
alert(hasIEPlugin("ShockwaveFlash.ShockwaveFlash")); // 检测IE浏览器是否有Flash
鉴于检测每种插件的方法差别比较大,因此典型的做法是针对每个插件分别创建检测函数。
// 检测所有浏览器中的Flash
function hasFlash(){
var result = hasPlugin("Flash");
if(!result){
result = hasIEPlugin("ShockwaveFlash.ShockwaveFlash");
}
return result;
}
注册处理程序
navigator对象新增了registerContentHandler()和registerProtocolHandler()方法,这两个方法可以让一个站点指明它可以处理特定类型的信息。
registerContentHandler()方法接收三个参数:要处理的MIME类型、可以处理该MIME类型的页面的URL以及应用程序的名称。
registerProtocolHandler()方法接收三个参数:要处理的协议、可以处理该协议的页面的URL以及应用程序的名称。
screen对象
screen对象基本上只用来表明客户端的能力,其中包括浏览器窗口外部的显示器的信息,如像素宽度和高度。
每个浏览器中screen对象都包含着各不相同的属性。
history对象
history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。
因为history对象是window对象的属性,因此每个浏览器的窗口、每个标签页乃至每个frame,都有自己的history对象与特定的window对象关联。
开发人员无法得知用户浏览过的URL。
go()
使用go()方法可以在用户的历史记录中任意跳转。
该方法接受一个参数,表示向前或向后跳转的页面数的一个整数值。负数表示向后跳转,正数表示向前跳转。
history.go(1); // 前进一页
history.go(-1); // 后退一页
history.go(2); // 前进两页
也可以给go()方法传递一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置—— 可能后退也可能前进,具体要看哪个位置最近。如果历史记录中不包含该字符串,那么这个方法什么也不做。
还可以使用back() 和 forward() 来代替 go()。
history.go(1); == history.forward();
history.go(-1); == history.back();
length属性
history对象存在length属性,保存着所有历史记录的数量(向前和向后)。
对于加载到窗口、标签页或框架中的第一个页面而言,history.length等于0。
if(history.length == 0){
// 这应该是用户打开窗口后的第一个页面
}