概念:BOM 的核心对象是 window,它表示浏览器的一个实例。在浏览器中,window 对象有双重角色,它既是经过 JavaScript 访问浏览器窗口的一个接口,又是 ECMAScript 规定的 Global 对象。这意味着在网页中定义的任何一个对象、变量和函数,都以 window 做为其 Global 对象,所以有权访问parseInt()等方法javascript
全局做用域:html
全部在全局做用域中声明的变量、函数都会变成 window 对象的属性和方法java
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;
窗口关系及框架浏览器
窗口位置缓存
肯定和修改 window 对象位置的属性和方法安全
var leftPos = (typeof window.screenLeft == "number") ? window.screenLeft : window.screenX; var topPos = (typeof window.screenTop == "number") ? window.screenTop : window.screenY;
将窗口精确地移动到一个新位置:服务器
moveTo():接收两个参数,新位置的 x 和 y 坐标值app
//将窗口移动到屏幕左上角 window.moveTo(0,0); //将窗口移动到(200,300) window.moveTo(200,300);
moveBy():在水平和垂直方向上移动的像素数
//将窗向下移动 100 像素 window.moveBy(0,100); //将窗口向左移动 50 像素 window.moveBy(-50,0);
窗口大小
肯定一个窗口的大小
肯定页面视口的大小
在 IE、Firefox、Safari、Opera 和 Chrome 中,document.documentElement.clientWidth 和
document.documentElement.clientHeight 中保存了页面视口的信息
在 IE6 的混杂模式,就必须经过 document.body.clientWidth 和 document.body.
clientHeight 取得相同信息
混杂模式下的 Chrome,则不管经过 document.documentElement仍是 document.body 中的 clientWidth 和 clientHeight 属性,均可以取得视口的大小
var pageWidth = window.innerWidth; var 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; } }
调整浏览器窗口的大小的方法:
//调整到 100×100 window.resizeTo(100, 100); //调整到 200×150 window.resizeBy(100, 50); //调整到 300×300 window.resizeTo(300, 300);
导航和打开窗口
window.open()方法
4 个参数:要加载的 URL、窗口目标、一个特性字符串以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值
一般只须传递第一个参数,最后一个参数只在不打开新窗口的状况下使用
若是为 window.open()传递了第二个参数,并且该参数是已有窗口或框架的名称,那么就会在具备该名称的窗口或框架中加载第一个参数指定的 URL,第二个参数也能够是下列任何一个特殊的窗口名
称:_self、_parent、_top 或_blank;
//等同于< a href="http://www.wrox.com" target="topFrame"></a> window.open("http://www.wrox.com/", "topFrame");
弹出窗口
若是给 window.open()传递的第二个参数并非一个已经存在的窗口或框架,那么该方法就会根
据在第三个参数位置上传入的字符串建立一个新窗口或新标签页
若是没有传入第三个参数,那么就会打开一个带有所有默认设置(工具栏、地址栏和状态栏等)的新浏览器窗口(或者打开一个新标签页——根据浏览器设置)
在不打开新窗口的状况下,会忽略第三个参数
第三个参数是一个逗号分隔的设置字符串,表示在新窗口中都显示哪些特性
window.open("http://www.wrox.com/","wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes");
window.open()方法会返回一个指向新窗口的引用
var wroxWin = 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);
调用 close()方法还能够关闭新打开的窗口
wroxWin.close(); alert(wroxWin.closed); //true
新建立的 window 对象有一个 opener 属性,其中保存着打开它的原始窗口对象
var wroxWin = window.open("http://www.wrox.com/","wroxWindow", "height=400,width=400,top=10,left=10,resizable=yes"); alert(wroxWin.opener == window); //true
在 Chrome中,将新建立的标签页的 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!"); }
间歇调用和超时调用
间歇调用:每隔指定的时间就执行一次代码
使用 window 对象的 setTimeout()方法,它接受两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前须要等待多少毫秒)
第一个参数能够是一个包含 JavaScript 代码的字符串(就和在 eval()函数中使用的字符串同样),也能够是一个函数
//不建议传递字符串! setTimeout("alert('Hello world!') ", 1000); //推荐的调用方式 setTimeout(function() { alert("Hello world!"); }, 1000);
第二个参数是一个表示等待多长时间的毫秒数,但通过该时间后指定的代码不必定会执行
调用 setTimeout()以后,该方法会返回一个数值 ID,表示超时调用。这个超时调用 ID 是计划执行代码的惟一标识符,能够经过它来取消超时调用。要取消还没有执行的超时调用计划,能够调用clearTimeout()方法并将相应的超时调用 ID 做为参数传递给它
//设置超时调用 var timeoutId = setTimeout(function() { alert("Hello world!"); }, 1000); //注意:把它取消 clearTimeout(timeoutId);
超时调用的代码都是在全局做用域中执行的,所以函数中 this 的值在非严格模式下指向 window 对象,在严格模式下是 undefined
超时调用:在指定的时间事后执行代码
使用 window 对象的 是 setInterval()方法,它接受两个参数:要执行的代码和以毫秒表示的时间(即在执行代码前须要等待多少毫秒)
//不建议传递字符串! setInterval ("alert('Hello world!') ", 10000); //推荐的调用方式 setInterval (function() { alert("Hello world!"); }, 10000);
调用 setInterval()方法一样也会返回一个间歇调用 ID,该 ID 可用于在未来某个时刻取消间歇调用。要取消还没有执行的间歇调用,可使用 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); //超时调用实现(最佳模式) var num = 0; var max = 10; function incrementNumber() { num++; //若是执行次数未达到 max 设定的值,则设置另外一次超时调用 if (num < max) { setTimeout(incrementNumber, 500); } else { alert("Done"); } } setTimeout(incrementNumber, 500);
系统对话框
alert()方法:接受一个字符串并将其显示给用户。具体来讲,调用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 和 Cancel 按钮以外,还会显示一个文本输入域,以供用户在其中输入内容;接受两个参数:要显示给用户的文本提示和文本输入域的默认值(能够是一个空字符串);若是用户单击了 OK 按钮,则 prompt()返回文本输入域的值;若是用户单击了 Cancel 或没有单击OK 而是经过其余方式关闭了对话框,则该方法返回 null
var result = prompt("What is your name? ", ""); if (result !== null) { alert("Welcome, " + result); }
除了上述三种对话框以外,Google Chrome 浏览器还引入了一种新特性。若是当前脚本在执行过程当中会打开两个或多个对话框,那么从第二个对话框开始,每一个对话框中都会显示一个复选框,以便用户阻止后续的对话框显示,除非用户刷新页面
还有两个能够经过 JavaScript 打开的对话框,即“查找”和“打印”。这两个对话框都是异步显示的,可以将控制权当即交还给脚本。这两个对话框与用户经过浏览器菜单的“查找”和“打印”命令打开的对话框相同。而在 JavaScript 中则能够像下面这样经过 window 对象的 find()和 print()方法打开它们
//显示“打印”对话框 window.print(); //显示“查找”对话框 window.find();
属性:
属 性 名 | 例 子 | 说 明 |
---|---|---|
hash | "#contents" | 返回URL中的hash(#号后跟零或多个字符),若是URL中不包含散列,则返回空字符串 |
host | "www.wrox.com:80" | 返回服务器名称和端口号(若是有) |
hostname | "www.wrox.com" | 返回不带端口号的服务器名称 |
href | "http://www.wrox.com" | 返回当前加载页面的完整URL。而location对象的<brtoString()方法也返回这个值 |
pathname | "/WileyCDA/" 返回URL中的目录和(或)文件名port "8080" | 返回URL中的目录和(或)文件名 |
port | "8080" | 返回URL中指定的端口号。若是URL中不包含端口号,则这个属性返回空字符串 |
protocol | "http:" | 返回页面使用的协议。一般是http:或https: |
search | "?q=javascript" | 返回URL的查询字符串。这个字符串以问号开头 |
查询字符串参数
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"
位置操做
assign()方法
location.assign("http://www.wrox.com");
location.href属性
location.href = "http://www.wrox.com";
每次修改 location 的属性(hash 除外),页面都会以新 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;
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>
reload()方法:从新加载当前显示的页面
location.reload(); //从新加载(有可能从缓存中加载) location.reload(true); //从新加载(从服务器从新加载)
属性
window.navigator
检测插件
对于非 IE 浏览器,可使用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 类型,并尝试建立一个特定插件的实例
//检测 IE 中的插件 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());
plugins 集合有一个名叫 refresh()的方法,用于刷新 plugins 以反映最新安装的插件。这个方法接收一个参数:表示是否应该从新加载页面的一个布尔值。若是将这个值设置为 true,则会从新加载包含插件的全部页面;不然,只更新 plugins集合,不从新加载页面
注册处理程序
registerContentHandler()方法接收三个参数:要处理的 MIME 类型、能够处理该 MIME类型的页面的 URL 以及应用程序的名称
navigator.registerContentHandler("application/rss+xml", "http://www.somereader.com?feed=%s", "Some Reader");
registerProtocolHandler()方法接收三个参数:要处理的协议(例如,mailto 或 ftp)、处理该协议的页面的 URL 和应用程序的名称
navigator.registerProtocolHandler("mailto", "http://www.somemailclient.com?cmd=%s", "Some Mail Client");
screen 对象基本上只用来代表客户端的能力,其中包括浏览器窗口外部的显示器的信息,如像素宽度和高度等;这些信息常常集中出如今测定客户端能力的站点跟踪工具中,但一般不会用于影响功能。不过,有时候也可能会用到其中的信息来调整浏览器窗口大小,使其占据屏幕的可用空间
window.resizeTo(screen.availWidth, screen.availHeight);
涉及移动设备的屏幕大小时,状况有点不同。运行 iOS 的设备始终会像是把设备竖着拿在手里一
样,所以返回的值是 768×1024。而 Android 设备则会相应调用 screen.width 和 screen.height 的值
history 对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。由于 history 是 window对象的属性,所以每一个浏览器窗口、每一个标签页乃至每一个框架,都有本身的 history 对象与特定的window 对象关联
使用 go()方法能够在用户的历史记录中任意跳转,能够向后也能够向前。这个方法接受一个参数,表示向后或向前跳转的页面数的一个整数值。负数表示向后跳转(相似于单击浏览器的“后退”按钮),正数表示向前跳转(相似于单击浏览器的“前进”按钮)
//后退一页 history.go(-1); //前进一页 history.go(1); //前进两页 history.go(2);
也能够给 go()方法传递一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置——可能后退,也可能前进,具体要看哪一个位置最近。若是历史记录中不包含该字符串,那么这个方法什么也不作
//跳转到最近的 wrox.com 页面 history.go("wrox.com"); //跳转到最近的 nczonline.net 页面 history.go("nczonline.net");
另外,还可使用两个简写方法 back()和 forward()来代替 go()。顾名思义,这两个方法能够模仿浏览器的“后退”和“前进”按钮
//后退一页 history.back(); //前进一页 history.forward();
history 对象还有一个 length 属性,保存着历史记录的数量。这个数量包括全部历史记录,即全部向后和向前的记录。对于加载到窗口、标签页或框架中的第一个页面而言,history.length 等于 0。经过像下面这样测试该属性的值,能够肯定用户是否一开始就打开了你的页面
if (history.length == 0){ //这应该是用户打开窗口后的第一个页面 }
一、浏览器对象模型(BOM)以 window 对象为依托,表示浏览器窗口以及页面可见区域。同时,window
对象仍是 ECMAScript 中的 Global 对象,于是全部全局变量和函数都是它的属性,且全部原生的构造函数及其余函数也都存在于它的命名空间下。本章讨论了下列 BOM 的组成部分:
二、BOM 中还有两个对象:screen 和 history,但它们的功能有限。screen 对象中保存着与客户端显示器有关的信息,这些信息通常只用于站点分析。history 对象为访问浏览器的历史记录开了一个小缝隙,开发人员能够据此判断历史记录的数量,也能够在历史记录中向后或向前导航到任意页面