浏览器对象模型(Browser Object Model)是语言核心和DOM之间的一个过渡层,这个过渡层特指Javascript的客户端实现,它的主要任务是管理浏览器窗口并使得它们可以彼此通信。window对象是BOM的核心。事实上,window对象还定义了诸如当前页的URL、浏览器的识别字符串等非文档结构的部分。

WHAT-WG正在为BOM指定一个规范,BOM正遵循着Netscape 3的事实标准。

window对象

window对象首先是核心需要的全局对象,它包含了脚本中定义的所有全局变量和函数。

在一次会话中,一个window对象可以包含很多页面,新页面会被载入到同一个window对象,window对象原来的全局对象(变量和函数)将被销毁,但是window对象本身并没有被销毁,它仍旧可以被访问到,甚至用户关闭了主窗口。

有三种方法来保存上一次的全局变量,cookie,跨浏览器通信和保存到服务器,第三种方法是最安全的。

新窗口会创建一个新的window对象,当创建一个其他窗口的window对象的引用时,访问这个引用的属性将报错,原因在使用引用时,引用尚未完全载入。正确的方法应该是为两个窗口的存在和释放各记录一个cookie,然后再调用方法钱检查这些状态。

window和self都指向窗口本身,它们访问的是同一个对象,习惯上使用window。

可以为name属性赋值,window.name='myname',这将为链接的target属性提供一个引导。window.open()方法也可以用到这个name作为打开窗口的目标。

window.status属性直接访问并重写状态了文本,window.defaultStatus提供了没有状态时状态栏的文本。可以使用a标签的mouseover方法修改掉默认的鼠标滑过链接显示href的动作,特殊的,在onmouseover中,IE和Mozilla都需要你返回true,而不是false来阻止整个默认动作。

跨浏览器通信

必须同时满足两个条件才能进行窗口间的通信:两个窗口必须来自同一个域(同源策略);其中一个窗口包含另一个窗口的引用(即一个窗口打开了另一个窗口)。

window.open方法用来打开新窗口,完整地书写window.open()而不是open()是为了与document.open()区别。

window.open('page.html', 'popup', 'width=300,height=400');

第一个参数指定载入的页面,为空则打开空白窗口,第二个参数设置新窗口的name值或打开已有name的窗口,第三个参数控制新窗口的外观和行为,详细的介绍在http://www.quirksmode.org/popups.html

保存window.open的返回值,则在主窗口创建了一个指向新窗口的引用,而新窗口总是自动创建一个opener属性指回主窗口。

当主窗口载入一个新页面时,弹出窗口的opner属性仍然指向主窗口(主窗口window对象没有销毁),但主窗口原来指向弹出窗口的全局变量被销毁了(此时仍满足跨窗口通信的第二个条件),我们需要重新建立联系:首先在弹出窗口建立一个函数,opener.newWindow=window(注意opener即为主窗口),按照上面的方法设置两个cookie来安全地在主窗口中调用弹出窗口的这个函数。考虑到同源策略和主窗口是否关闭,弹出窗口的这个函数应该写为:

if (!opener || opener.closed ||!checkCommunication()) {
//exit actions
} elseif (checkCommunication() && opener.ST_loaded) {
opener.ST_newWindow = window;
tryCounter =;
} elseif (tryCounter < nrOfAttempts) {
//record the new site
tryCounter++;
} else {
//exit actions
}

首先判断opner为null(虽然罕见但是保险起见)、是否关闭、能否通信,然后检查主窗口的ST_loaded属性(自定义用来确认完全载入),最后判断尝试通信超过指定次数。

在这里我们用到了window.closed属性,我们讲窗口释放时所有的全局变量都被销毁,但是除少数浏览器外都保留了closed属性用来指示是否关闭,而对于其他属性诸如location和navigation是否仍存在,各个浏览器并没有对此达成一致,因此窗口释放时除closed属性外不要再使用。

(bloodmage按:在这里我提到了对象、变量、属性、方法、函数,实际上,javascript不区分属性和变量,也不区分方法和函数,只是习惯上单独使用时讲变量和函数,而谈到对象时则用属性和方法;我讲窗口释放时所有的全局对象都被销毁,是指window对象的属性和方法都被销毁了,而实际上window对象的属性即location,document.navigation,screen等也是对象,window对象的方法则主要有表示交互的alert和改变大小的resizeTo等。)

当违反同源策略(详见笔记一)时,不能从该窗口中收集它的任何信息,通过尝试来检查能否通信。

function checkCommunication() {
if (!opener) returnfalse;
try {
opner.testVar =true;
} catch(e) {
returnfalse;
}
returntrue;
}

window.close()方法用来关闭窗口,但一些浏览器拒绝执行,或者弹出一个对话框询问是否关闭窗口。通过javascript打开的窗口可以直接被关闭而不被提示,因此可以使用使用window.open('','_self');window.close();直接关闭当前窗口。

由于弹出窗口的恶名,浏览器默认开启Block unrequested popup windows功能阻止打开未经请求的弹出窗口,但这很容易被绕过,比如设置document.onclick = function() { window.open(); }。新的窗口拦截软件提供了更多的方法,但同时恶意广告也会利用flash、微软专有的popup对象或脚本创建内嵌层模拟弹窗。

导航

ppk on javascript 笔记(六)--BOM的更多相关文章

  1. JavaScript笔记六

    1.对象(Object) - 对象是JS中的引用数据类型 - 对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性 - 使用typeof检查一个对象时,会返回object - 创建对象 - ...

  2. 【学习笔记】:JavaScript中的BOM对象

    JavaScript中的BOM对象 BOM(Browser Object Model):浏览器对象模型. BOM可用于对浏览器窗口进行访问,但BOM没有相关的标准,所以根据浏览器的不同,其中定义的对象 ...

  3. 前端er是否忽略了某些东西?——读《ppk谈JavaScript》

    关于书 “不知道ppk的网站QuirksMode,说明你可能还没有真正成为资深的JavaScript程序员.” ——Roger Johansson,瑞典资深Web专家. ppk是世界级前端技术专家,W ...

  4. 从头开始学JavaScript 笔记(一)——基础中的基础

    原文:从头开始学JavaScript 笔记(一)--基础中的基础 概要:javascript的组成. 各个组成部分的作用 . 一.javascript的组成   javascript   ECMASc ...

  5. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  6. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  7. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  8. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  9. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

随机推荐

  1. mysql 语句的查询过程解析

    select * from tb where ID = 1 下面解析的查询过程都是基于上面的简单查询,该系列的所有素材都来自于丁奇的mysql的45讲 1.建立连接 a.客户端发出请求,请求首先到达连 ...

  2. thinkphp5.0 路由规则配置

    开启路由‘url_route_on’ => true 首页路由'/' =>'home/index/index' 其它路由(1)'route' => 'home/index/route ...

  3. 2019-9-23-dotnet-判断特定进程存在方法

    title author date CreateTime categories dotnet 判断特定进程存在方法 lindexi 2019-09-23 16:20:42 +0800 2019-09- ...

  4. [转]embedding technic:从SNE到t-SNE再到LargeVis

    http://bindog.github.io/blog/2016/06/04/from-sne-to-tsne-to-largevis/#top

  5. Nginx 缓存代理

    访问ArcGIS官网的地图瓦片太慢.想到可用NIGIX代理. Nginx是Linux下http代理软件,Windows下也有. 以下为配置方法,注意红色部分. 1.需要在本地proxy_cache_p ...

  6. Autodesk 卸载工具,一键完全彻底卸载删除autodesk软件专门卸载工具

    autodesk卸载工具(AUTO Uninstaller)是专门为了针对autodesk类软件卸载不干净而导致autodesk安装失败问题进行研发的autodesk一键卸载工具.现在虽然360或一些 ...

  7. AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle【暴力】

    AtCoder Beginner Contest 075 D - Axis-Parallel Rectangle 我要崩溃,当时还以为是需要什么离散化的,原来是暴力,特么五层循环....我自己写怎么都 ...

  8. TextView.setTextColor(int); 括号里那个颜色int值的理解

    原本以为是R.id里的东西,后来发现不是 http://dianhua1990627.blog.163.com/blog/static/2755558820132262150387/

  9. nodeJs学习-06 模块化、系统模块、自定义模块、express框架

    系统模块:http://nodejs.cn/api/events.html 自定义模块: require   请求:引入模块 module    模块:批量输出 exports   输出:单独输出   ...

  10. Python基础:06条件和循环

    1:条件表达式(三元操作符) Python 在很长的一段时间里没有条件表达式(C ? X : Y), 或称三元运算符.人们试着用 and 和 or 来模拟它, 但大多都是错误的. 根据 FAQ , 正 ...