浏览器对象模型BOM
访问和操作浏览器窗口的模型称为浏览器对象模型BOM(Browser Object Model),但习惯上是把所有针对浏览器的JavaScript扩展都纳入BOM的范畴。BOM提供了一组独立于网页内容而与浏览器交互的对象,但由于缺乏相关的行业规范,各浏览器提供商在很长一段时间内都是按照各自的想法去实现这些对象的,因而浏览器之间共有的对象也就成为了事实上的标准,这种局面在HTML5出现后有望得到改观——HTML5致力于把很多BOM功能写入正式规范。由于不同浏览器之间的差异性,这里总结的主要是一些我认为比较常用的共有的特性,至于开发过程中的兼容性考虑,就交给流行的JS库吧(比如jQuery、ExtJS)。
先看一下下面的这个BOM对象图,从整体上对BOM有个认识:
上图中的window、document和location对象都具有双重身份:window对象既是ECMAScript规范中的Global对象,也是BOM中的顶级对象;document对象既是BOM顶级对象的一个属性,也是DOM模型中的顶级对象;location对象既是window对象的属性,同时也是document对象的属性。在BOM中,核心是window对象,下面就重点总结一下这个对象,document对象将在学习DOM模型时再做说明。
一、window对象
1、window作为ECMAScript中的Global对象
(1)引用Global对象的属性和方法时可以省略对象名,因此在引用window对象的属性和方法时,也可以省略window。
(2)在全局作用域中this和window指向同一个对象,另外,还可以使用self来引用window对象,也即有this===window===self。
(3)在全局作用域中定义的变量和函数也会成为window对象的属性和方法,但是和直接在window对象上定义属性还是有区别:
A、全局变量不能使用delete删除(相当于给window定义属性时将属性特性[[Configurable]]赋值为false了),但是直接在window对象上定义的属性可以使用delete删除。这里有趣的是,如果同时定义了全局变量和window对象的属性,则删除window属性时不起作用。
B、尝试访问未定义的全局变量会抛出异常,但是访问未定义的window对象的属性则只是返回undefined。
var age = '29';//全局作用域中定义的变量和函数会成为window对象的属性和方法,但是不能使用delete删除 function getAge(){return this.age; } console.info(window.age); // 29 console.info(window.getAge()); // 29 console.info(this == window); // true console.info(this == self); // true console.info(window == self); // true window.age = '23';//直接在window对象上定义属性,会同时修改全局变量的值,相反,修改全局变量的值,window对象的属性值也会修改 console.info(age); delete window.age;//既定义了全局变量,又在window对象上定义了属性,删除时虽然没有报错,但是并没有起作用 console.info(age); //23 console.info(window.age); //23 window.color = 'red';//直接在window对象上定义属性,可以使用delete删除 console.info(window.color); delete window.color; console.info(window.color);//undefined
2、window作为BOM中的顶级对象
(1)窗口关系及框架
先来看看在BOM中几个具有特殊含义的对象top、window、parent、self:
- top:指向最高(最外)层的框架,也就是浏览器窗口。
- window:指向当前框架的顶层对象。
- parent:指向当前框架的直接上层框架,在没有子框架的情况下,parent、window、top和self都相等,在有子框架的情况下,parent有可能等于top,也有不能不相等。
- self:始终指向window,引入self的目的只是为了与top和parent对象对应起来。
如果页面中包含框架,则每个框架都有自己的window对象,并且保存在父窗口的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>
在最外层的页面中,可以通过下面的方式来访问其中的框架:
(2)window作为顶层对象的主要方法
属性和方法 | 返回值 | 参数 | 说明 | ||
位置方法 | moveTo(x,y) | x和y表示新位置的x和y坐标值 | |||
moveBy(x,y) | x和y表示在水平和垂直方向上移动的像素数 | ||||
大小方法 | resizeTo(x,y) | x和y表示浏览器窗口的新宽度和新高度 | |||
resizeBy(x,y) | x和y表示浏览器窗口的新宽度、新高度和原宽度、原高度的差 | ||||
对话框 | 同步 | alert() | 提示文本 | 显示时包含传入的字符串和“确定”按钮 | |
confirm() | 点击“确认”返回true,点击“取消”返回false | 确认文本 | 显示时包含传入的字符串、“确认”按钮(返回true)和“取消”按钮(返回false),常用于确认删除操作 | ||
prompt() | 点击“确认”返回文本输入内容,点击“取消”返回null | 提示文本、文本输入域 | 显示时包含文本提示、“确认”按钮(返回文本输入域的内容)、“取消”按钮(返回null)和文本输入域。 | ||
异步 | find() | 相当于使用浏览器菜单栏的“查找”命令打开对话框 | |||
print() | 相当于使用浏览器菜单栏的“打印”命令打开对话框 | ||||
调度 | 超时 | setTimeOut() | 返回一个数值ID表示这个调用 | 执行函数或代码、执行代码前需要等待的时间(毫秒) |
JavaScript是单线程的,超时调用和循环调用中的时间表示将需要执行的函数或代码加入到执行队列的时间,而不是实际执行的时间,加入到执行队列之后一有资源就会马上执行。由于这个原因,setInterval()可能存在一些间隔会被跳过执行,也可能间隔时间比预期的小,因此不建议使用循环调用,而采用下面的链式超时调用模式:
setTimeout(function(){//处理代码 setTimeout(arguments.callee, time); }, time); |
clearTimeOut() | 根据ID取消超时调用 | 超时调用ID | |||
循环 | setInterval() | 返回一个数值ID表示这个调用 | 执行函数或代码、循环执行代码的间隔时间(毫秒) | ||
clearInterval() | 根据ID取消循环调用 | 循环调用ID | |||
新窗口 | 普通 | open() | 返回新打开窗口的引用 | 4个参数:目标URL,目标窗口名称,特性字符串,是否取代历史记录中当前加载页面的Boolean值 |
通常只需传递第一个参数,最后一个参数只在不打开新窗口的情况下使用。 如果传递了第二个参数,而且该参数是已有窗口或框架的名称,那么就会在相应的窗口或框架中加载目标URL,如果是一个不存在的名称,就会创建一个新窗口。第二个参数也可以是下面的特殊值:_self、_parent、_top、_blank。 |
说明:
A、表示窗口位置的属性有screenLeft、screenTop、screenX、screenY、表示窗口大小的属性有innerWidth、innerHeight、outerWidth、outerHeight,但是它们的具体含义和不同的浏览器密切相关,在上表中没有列入。这些属性的差异性给窗口控制的兼容性造成了非常大的困扰,不过好在现在已经有很多成熟的JS框架,在处理浏览器差异性建议使用这些JS框架。
B、moveTo()、moveBy()、resizeTo()、resizeBy()四个方法不适用于框架,只适用于最外层的window对象,而且这些方法可能会被浏览器禁用(在Opera和IE7+中默认就是禁用的)。
C、window.open()方法中的第三个参数为特性字符串,是一个逗号分隔的设置字符串,用来表示在新窗口中都显示哪些特性,整个特性字符串不允许出现空格,特性和特性以逗号分隔,特性和特性值以等号(=)间隔。这些特性有(蓝色的为默认值):
特性 | 取值范围 | 说明 |
fullscreen | yes|no | 表示浏览器窗口是否全屏,仅限IE |
height | 数值(不能小于100) | 新窗口的高度 |
width | 数值(不能小于100) | 新窗口的宽度 |
left | 数值(不能是负值) | 新窗口的左坐标 |
top | 数值(不能是负值) | 新窗口的上坐标 |
toolbar | yes|no | 是否在浏览器窗口中显示工具栏 |
status | yes|no | 是否在浏览器窗口中显示状态栏 |
scrollbars | yes|no | 如果内容在视口中显示不下,是否显示滚动条 |
resizable | yes|no | 是否可以通过拖动浏览器窗口的边框来改变其大小 |
menubar | yes|no | 是否在浏览器窗口中显示菜单栏 |
location | yes|no | 是否在浏览器窗口中显示地址栏,不同浏览器默认值不同,如果设置为no,地址栏可能会隐藏,也可能会被禁用 |
D、window.open()方法返回新创建窗口的一个引用,可以利用这个引用来操作新窗口,新窗口对象中有一个opener属性指向原窗口。
//创建新窗口,返回这个新窗口对象的引用,如果代码是在新打开窗口的页面,则可以直接通过window访问 var openWin = window.open("http://www.cnblogs.com/linjisong","cnblogs-lin","height=400,width=320,resizable=yes"); openWin.resizeTo(800,600);//重新定义大小 openWin.moveTo(100,100);//移动位置 console.info(openWin.opener === window);//true,新窗口对象中有一个opener属性指向原窗口 openWin.close();//关闭新窗口 console.info(openWin.closed);//true,关闭之后可以访问关闭状态
在使用window.open()方法时,出于安全性考虑,很多浏览器会有一些限制,比如Firefox强制显示地址栏等,在实际开发过程中,需要根据目标浏览器来测试这些限制并采取相应的措施。
E、在IE中,除了window.open()之外,还可以通过window.showModelDialog()来弹出一个窗口,通常称之为“模态窗口”,这种窗口会独占系统资源,用户只有在关闭它之后才能继续其它的操作。由于模态窗口不是兼容所有浏览器,这里不再展开,有兴趣的朋友可以找相应的资料了解一下。
二、history对象
history对象保存着从窗口被打开起的历史记录,每个浏览器窗口、标签页、框架都有自己的history对象。history对象的主要属性和方法有:
属性/方法 | 例子 | 说明 |
length | if(history.length == 0) //第一个页面 | 历史记录的数量 |
go() |
history.go(-1); history.go(0); history.go(2); history.go('linjisong'); |
负数表示向后跳转 0表示刷新当前页面 正数表示向前跳转 字符串参数,表示跳转到历史记录中包含该字符串的最近一个位置(可能前进,也可能后退) |
back() | history.back();相当于history.go(-1); | 后退一页,可模仿浏览器“后退”按钮 |
forward() | history.forward();相当于history.go(1); | 前进一页,可模仿浏览器“前进”按钮 |
三、location对象
location对象提供了与当前窗口中加载的文档有关的信息以及一些导航功能,它既是window对象的属性,同时也是document对象的属性,它的主要属性和方法有:
属性/方法 | 例子 | 说明 |
hash | "#contents" | 返回URL中的hash(#号后跟零或多个字符),如果URL中不包括散列,返回空字符串 |
host | "www.wrox.com:80" | 返回服务器名称和端口号(如果有) |
hostname | "www.wrox.com" | 返回不带端口号的服务器名称 |
href | "http://www.wrox.com" | 返回当前加载页面的完整URL,location对象的toString()方法也返回这个值 |
pathname | "/WileyCDA" | 返回URL中的目录和文件名 |
port | "8080" | 返回URL中指定的端口号,如果不含端口号,返回空字符串 |
protocol | "http:" | 反应页面使用的协议,通常是http:或https: |
search | "?q=javascript" | 返回URL的查询字符串,这个字符串以问号开头 |
assign() | location.assign(URL) | 立即打开新URL并在浏览器历史中生成一条记录,相当于直接设置location.href值,也可以修改location对象的其它属性来重新加载 |
replace() | location.replace(URL) | 打开新URL,但是不会生成历史记录,使用replace()之后,用户不能通过“后退”回到前一个页面 |
reload() | location.reload([true]) | 重新加载当前页面,不传递参数时会以最有效方式加载(可能从缓存中加载),传入true时,则强制从浏览器重新加载 |
说明:location.search返回的是包括所有参数的字符串,可以通过下面的方法将这个字符串转换为一个参数对象(原书第207页):
function getQueryStringArgs(){var qs = (location.search.length > 0 ? location.search.substring(1) : ""),//去掉查询字符串前面的问号args = {},items = qs.length ? qs.split("&") : [],//将参数以&分隔item = null,name = null,value = null,i = 0,len = items.length;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;}var args = getQueryStringArgs();//假定查询字符串返回?q=javascript&num=10 console.info(args["q"]); //"javascript"console.info(args["num"]); //"10"
注意:该方法对于查询字符串中同一个参数多个值的情况(类似?val=1&val=2)处理会有问题。
四、navigator对象
navigator对象用来描述浏览器本身,包括浏览器的名称、版本、语言、系统平台、用户特性字符串等信息,但是各个浏览器及浏览器的不同版本之间对这个对象的实现也不尽相同。
在非IE浏览器中,可以使用navigator对象的plugins属性来检测插件的安装情况:
function hasPlugin(name){name = name.toLowerCase();for (var i=0; i < navigator.mimeTypes.length; i++){if (navigator.mimeTypes[i].name.toLowerCase().indexOf(name) > -1){return true;}}return false; }
也可以使用navigator对象的userAgent属性(用户代理字符串)来检测客户端对某种功能的支持情况。不过在检测浏览器是否支持某种功能的时候,首先应使用特性检测来判断,特性检测的目标不是判断是什么浏览器,而是判断浏览器是否支持某种能力,比如在IE早期版本中不存在document.getElementById(),而是使用非标准的document.all来获取DOM元素,就可以使用如下代码:
function getElement(id){if(document.getElementById){//特性检测,如果支持,优先使用document.getElementById()return document.getElementById(id); }else{return document.all[id];} }
有时候虽然支持某种特性,但是这种特性并不是想要的功能,这种情况下,可以对特性进一步做检测,比如通过下面的代码进一步判断支持的特性是否为函数:
typeof document.createElement === 'function'
当然,特性检测并不总是能凑效,这时不得已就只好通过navigator对象来对检测了,因为userAgent是在浏览器发展过程中逐步演变而来的,因此使用这种检测技术需要了解各种浏览器的发展历史,这里就不具体展开了,建议就是使用成熟的JS库来代替直接使用navigator.userAgent进行检测。
五、screen对象
screen对象用来表明客户端的能力,包括浏览器窗口外部的显示器的信息,如像素宽度和高度等,每个浏览器中的screen对象都包含着各不相同的属性,其中五大浏览器都支持的属性有:
- height:屏幕的像素高度
- width:屏幕的像素宽度
- availHeight:屏幕的像素高度减系统部件高度之后的值(只读)
- availWidth:屏幕的像素宽度减系统部件宽度之后的值(只读)
screen对象经常集中出现在测定客户端能力的站点跟踪工具中,有时候也可能会用到其中的信息来调整浏览器窗口的大小,使其占据屏幕的可用空间,比如:
window.resizeTo(screen.availWidth, screen.availHeight);
浏览器对象模型BOM相关推荐
- js笔记(四)内置对象Math和Date()、浏览器对象模型BOM
大标题 小标题 备注 一.内置对象Math.Date() 1. Math 数学对象; 2. Date() 日期对象; 常用的数学对象:Math.PI.abs(n).round(n).random(). ...
- 浏览器对象模型bom的作用是什么?
浏览器对象模型bom的作用是什么? 零.总结 1.BOM提供了独立于内容而与浏览器窗口进行交互的对象 2.BOM提供了一些访问窗口对象的一些方法,我们可以用它来移动窗口位置,改变窗口大小,打开新窗口和 ...
- JavaScript浏览器对象模型BOM
JavaScript浏览器对象模型BOM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- 浏览器对象模型(BOM)
BOM结构 用户浏览网页的时候,浏览器会自动创建一些对象,这些对象存放着浏览器窗口的属性和相关信息,也就是大家熟称的BOM.浏览器对象模型是一个层次化的对象集,我们可以通过window对象访问所有对象 ...
- 浏览器对象模型BOM学习
BOM 浏览器对象模型 BM可以使我们通过JS来操作浏览器 在BOM中为我们提供了一组对象,用来完成对浏宽器的操作 B0M对象 Window 代表的是整个浏览器的窗口,同时window也是网页中的全局 ...
- 什么是BOM BOM概述 浏览器对象模型 BOM的构成
什么是BOM BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window: BOM是由一些列相关对象构成,并且每个对象 ...
- 浏览器对象模型 (BOM)
浏览器 目前主流的浏览器分这么几种: IE 6~11:国内用得最多的IE浏览器,历来对W3C标准支持差.从IE10开始支持ES6标准: Chrome:Google出品的基于Webkit内核浏览器,内置 ...
- 前端之浏览器对象模型(BOM)
1.BOM 概念: BOM(Browser Object Model) 是指浏览器对象模型,浏览器对象模型提供了独立于内容的.可以与浏览器窗口进行互动的对象结构.BOM由多个对象组成,其中代表浏览器窗 ...
- JavaScript学习总结(一)——ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)...
一.JavaScript简介 JavaScript是一种解释执行的脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型,它遵循ECMAScript标准.它的解释器被称为JavaScript引 ...
最新文章
- 隔离太无聊?每天一个数据科学项目,数据集都准备好了!
- The final five question form qhpMaster
- 函数计算的开发与配置
- 中国湿敏元器件市场研发方向预测与前景趋势研究报告2022版
- PHP导入Excel和导出Excel
- 【转】C# Stream篇(—) -- Stream基类
- 从国际站 - M 站建设谈开发者产品思维
- 共享内存 传一个类指针_大神是如何学习 Go 语言之为什么使用通信来共享内存...
- LeetCode刷题(20)
- linux系统制作win安装盘,在Ubuntu Linux下制作Windows 启动安装 USB盘
- [转]魔兽世界私服Trinity,从源码开始
- 3d打印实用小工具--GCode Viewer在线预览GCODE文件
- Layui的TreeTable使用
- 或许你一辈子都是个小人物
- 层次分析法原理讲解 python手搓实现-故事带入小白详解版
- 周围剃光头顶留长发型_为什么很多秃顶的人,宁可留周围一圈头发,也不直接剃成光头?...
- Linux regulator框架理解及使用
- 虚拟机桌面切换命令行
- 抖音矩阵号搭建及开发思路分享丨抖音矩阵源码丨抖音矩阵号运营
- 排序算法 - 冒泡排序
热门文章
- 【Linux 内核】编译 Linux 内核 ① ( 下载指定版本的 Linux 内核源码 | Linux 内核版本号含义 | 主版本号 | 次版本号 | 小版本号 | 稳定版本 )
- 【五线谱】踏板标记 ( 踩下踏板 Ped 标记 | 松开踏板 * 标记 | MIDI 中的对应踏板指令 | 连续控制信号 | 开关控制信号 )
- 【Git】Git 分支管理 ( 解决分支合并冲突 | 本地处理文件冲突 )
- 【Flutter】Flutter 启动白屏问题 ( 问题描述 | 在 launch_background.xml 中设置启动过渡 UI )
- 【错误记录】Android 编译时技术版本警告 ( 注解处理器与主应用支持的 Java 版本不匹配 )
- IOS文本框readonly时焦点事件
- 末学者daylight__Linux磁盘管理及LVM
- [NOIP2017]逛公园 最短路+拓扑排序+dp
- 希尔排序(Shell's Sort)的C语言实现
- oracle得到日期对应的星期