【JS红宝书学习】8BOM

BOM提供了很多对象,用于访问浏览器的功能,这些功能与网页无关。W3C把浏览器中JavaScript最基本的部分标准化,已经将BOM的主要方面纳入了HTML5规范中。

1、window对象

BOM的核心对象是window,他表示浏览器的一个实例。在浏览器中,window对象有双重角色,它既是通过JavaScript访问浏览器窗口的一个接口,又是ECMAScript规定的Global对象。这意味着在网页中定义的任何一个对象、变量、函数,都以window作为其Global对象,因此有权访问parseInt()等方法。window对象的属性有很多,比如location和navigator。
1、全局作用域
所有在全局作用域声明的变量和函数都会变成window对象的属性和方法。全局变量不可以通过delete操作符删除,而直接定义在window对象上的属性可以被删除。同时,任何尝试访问未声明的变量会抛出错误,但是在查询对象的属性的时候,只会出现undefined,所以如果是使用全局变量的方式查询一个变量,将会出错;而使用window对象查询时,则不会。
2、窗口关系及框架
如果页面中包含框架,则每个框架都拥有自己的window对象,并且保存在frams集合中。在frames集合中,可以通过数值索引(从0开始,从左至右,从上到下)或者框架名称来访问相应的window对象。

<frameset row="160,*">
    <frame src="frame.html" name="topFrame"></frame>
    <frameset cols="50%,50%">
        <frame src="anotherframe.html" name="leftFrame"></frame>
        <frame src="yetanotherframe.html" name="rightFrame"></frame>
    </frameset>
</frameset>

上述代码创建了一个框架集(T型,上面一个top,下面一个left,一个right)。对于这个例子,可以通过window.frame[0]或者window.frames[“topFrame”]来引用上访的框架。不过,最好是用top而非window来引用这些框架(比如top.frames[0])。
我们知道top对象始终指向最高(最外)层的框架,也就是浏览器窗口。使用它可以确保在一个框架中正确地访问另一个框架。因为对于在一个框架中便携的任何代码来说,其中的window对象指向的都是那个框架的特定实例,而非最高层框架。
如果要访问最高层框架

window.frames[0];
window.frames["topFrame"];
top.frames[0];
top.frames["topFrame"];
frames[0];
frames["topFrame"];

访问右下角的frame

window.frames[2];
window.frames["rightFrame"];
top.frames[2];
top.frames["rightFrame"];
frames[2];
frames["rightFrame"];

与top相对的另一个window对象是parent。parent对象始终指向当前框架的直接上层框架。在某些情况下top个parent可能是等价的。
注意,除非最高层窗口是通过window.open()打开的,否则其window对象的name属性不会包含任何值。
与框架有关的最后一个对象是self,它始终指向window,实际上window和self对象可以互换使用,引入self对象的目的只是为了与top和parent对应起来。
所有这些对象都是window对象的属性,可以通过window.parent、window.top等形式来访问。同时也意味着可以链式使用,比如window.parent.parent.frames[0];

3、窗口位置
用来修改window对象位置的属性和方法有很多。
首先就是IE、Safari、Opera、Chrome提供了screenLeft和screenTop属性,分别表示窗口相对于屏幕左边和上边的位置。同时,Firefox提供了screenX,screenY与之对应,Safari和Chrome也提供了这两个属性。但是要注意,虽然Opera也提供了screenX,screenY,但是其值并不与screenLeft和screenTop对应,所以我们应当使用下面的代码来查看。

var leftPos = (typeof window.screenLeft == 'number')?
                window.screenLeft : window.screenX;
var topPos = (typeof window.screenTop =="number")?
                window.screenLeft : window.screenY;
console.log(leftPos);//0
console.log(topPos);//0

但是,这样使用不是很精确,因为浏览器实现的缘故,IE、Opera这两个值保存的是window对象表示的区域到左上角的距离;Chrome、Firefox和Safari,保存的是整个浏览器窗口相对于屏幕的坐标值,并且始终返回页面每个框架的top.screenX和top.screenY的值。
不过我们可以借助moveTo()和moveBy()方法将窗口精确地移动到一个新位置。
这两个方法都接受两个参数,其中moveTo()方法接受的是新位置的x、y坐标,moveBy()接受的是在水平和垂直方向上移动的像素值。

4、窗口大小
浏览器提供了四个属性,innerWidth、innerHeight、outerWidth、outerHeight。outerWidth和outerHeight返回浏览器窗口本身尺寸。innerWidth和innerHeight返回该Opera容器(就是标签页)中页面视图区域的大小,其他浏览器中inner相比outer要减去边框宽。Opera中,outer表示的是容器(标签页)大小,inner表示的是容器中试图去大小(减去边框大小)。在Chrome中,outer和inner返回相同的值,都表示视口(viewport)大小。
在IE、Firefox、Safari、Opera、Chrome中,document.documentElement.clientWidth和document.documentElement.clientHeight保存了页面视口的信息。在IE6中,必须要在标准模式下才有效;如果是混杂模式,就必须通过document.body.clientWidth和document.body.clientHeight取得相同的信息。而对于混杂模式下的Chrome,则两种方式都可以。
虽然最终无法获取浏览器窗口本身的大小,但是可以取得页面视口的大小。

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;
    }
}

另外可以通过resizeTo()和resizeBy()方法调整浏览器窗口的大小,都接受两个参数。其中resizeTo()方法两个参数分别为,改变后窗口的新宽度和新高度;resizeBy()方法两个参数分别为,改变后窗口的新宽度与当前宽度的差值和改变后窗口的新高度与当前高度的差值。

5、导航和打开窗口
runoob.com/jsref/met-win-open.html
使用window.open()方法既可以导航到一个特定的URL,也可以打开一个新的浏览器窗口。这个方法可以接受4个参数:要加载的URL、窗口目标、一个特性字符串以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。通常只需要传递第一个参数,最后一个参数只在不打开新窗口的情况下使用(也就是默认值是true)。
如果为window.open()传递了第二个参数,而且该参数是已有窗口或框架的名称,那么就会在具有改名称的窗口或框架中加载第一个参数指定的URL。

window.open("#","topFrame");
//等价于 <a href="#" target="topFrame"></a>

如果有一个名叫“topFrame”的框架或者窗口,就会在这个窗口或框架加载这个URL;否则就会创建一个新窗口并将其命名为“topFrame”。此外,第二个参数也可以是下列任何一个特殊的窗口名称:_self、_parent、_top或_blank。
弹出窗口:
如果给window.open()传递的第二个参数并不是已经存在的窗口或框架,那么该方法就会根据在第三个参数位置上传入的字符串创建一个新窗口或新标签页。如果没有传入第三个参数,那么久回打开一个带有全部默认设置(工具栏、地址栏和状态栏等)的新浏览器窗口(或者打开一个新标签页,这取决于浏览器的设置)。在不设置打开新窗口的情况下,会忽略第三个参数。
第三个参数是一个逗号分割的设置字符串,表示在新创口中都显示哪些特性。
在这里插入图片描述
比如

window.open("#","wroxFrame","height=400,width=400,top=10,left=10,resizable=yes");

这段代码会打开一个新的可以调整大小的窗口,窗口初始大小为400*400像素,并且距屏幕上沿和左边各10像素。

var newWin = window.open("#","wroxFrame","height=400,width=400,top=10,left=10,resizable=yes");
newWin.resizeTo(500,500);
newWin.moveTo(10,10);
newWin.close();
console.log(newWin.closed);//true
newWin.opener = null;

可以用close关闭使用window.open()打开的窗口。
使用closed属性来查看是否已关闭。
将opener属性设置成null就是告诉浏览器新创建的标签页不需要与打开它的标签页通信,因此可以在独立的进程中运行。标签页之间的联系一旦切断,将没有办法恢复。

安全限制:曾经有一段时间,广告商随意将弹出窗口打扮成系统对话框的样子,引诱用户去点击其中的广告。所以运营商开始对弹出窗口配置方面增加限制。比如window XP SP2中的IE6,不允许在屏幕之外创建弹出窗口、不允许将弹出窗口移动到屏幕以外,不允许关闭状态栏等。IE7不允许关闭地址栏、默认情况下不允许移动弹出窗口或调整其大小。

弹出窗口屏蔽程序:大多数浏览器都内置有弹出窗口屏蔽程序,而没有内置这些程序的浏览器也可以安装一些插件。如果是浏览器内置的弹出窗口屏蔽程序,则会使得window.open()的返回值为null;或者可能会让open方法报错。可以用以下代码检测。

var blocked = false;
try{
    var wrox = window.open("#","_blank");
    if(wrox == null) blocked = true;
}catch(ex){
    blocked = true;
}
if(blocked){
    alert("blocked");
}

6、间歇调用和超时调用
setTimeout()和setInterval(),clearTimeout()和clearInterval()
7、系统对话框
alert()、confirm()、prompt()
其中confirm和prompt会返回用户的选择或者输入的内容,如果点击取消或者右上角的叉号就会返回null

2、location对象

location提供了与当前窗口加载的文档有关的信息,还提供了一些导航功能。
在这里插入图片描述
hash:"#content",返回的是URL的hash值,就是#后面跟0或者多个字符,如果为空就返回空字符串。
search:"?q=javascript",返回的是URL的查询字符串。

1、查询字符串参数
可以根据&号来分割字符串,然后进行操作。
2、位置操作
使用location对象可以通过很多方式来改变浏览器的位置。首先,也是最常用的方式,就是使用assign()方法并为其传递一个URL。
location.assign("#");
这样就可以立即打开新URL并在浏览器的历史记录中生成一条记录。如果将location.href或者window.location设置成一个URL值,也会以这个值调用assign()方法,另外修改location的属性也会发生变化(比如hostname、port等等)。
使用上述任何一种方式修改URL后,浏览器的历史记录就会生成一条新记录,因此用户通过单击“后退”按钮都会导航到钱一个页面。要禁用这种行为,可以使用replace()方法。这个方法只接受一个参数,即要导航到的URL;结果虽然会导致浏览器位置改变,但不会在历史记录中生成新记录,也就意味着用户不能回到前一个页面。

3、navigator对象

navigator对象现在已经成为识别客户端浏览器的事实标准。

1、检测插件
检测浏览器中是否安装了特定的插件是一种最常见的检测例程。对于非IE浏览器,可以使用plugins数组。该数组每一项都包含以下的属性:
name:插件名
description:插件的描述
filename:插件的文件名
length:持剑所处理的MIME类型数量

//非IE版
function hasPlugin(name){
    name = name.toLowerCase();
    for(let i=0;i<navigator.plugins.length;i++){
        if(navigator.plugins.name.toLowerCase().indexOf(name)>-1)return true;
    }
    return false;
}

因为IE使用COM对象的方式实现插件的,而COM对象使用唯一标识符来标识,比如Flash的标识符是ShockwaveFlash.ShockwaveFlash.

function hasIEPlugin(name){
    try{
        new ActiveXObject(name);
        return true;
    }catch(ex){
        return false;
    }
}

2、注册处理程序
补充:RSS(Really Simple Syndication),简易信息聚合(也叫聚合内容)是一种基于XML的标准,在互联网上被广泛采用的内容包装和投递协议。
Firefox 2为navigator对象新增了registerContentHandler()和registerProtocolHandler()方法,这两个方法是在HTML5中定义的。这两个方法可以让一个站点指明它可以处理特定类型的信息。随着RSS阅读器和在线电子邮件程序的兴起,注册处理程序就为像使用桌面应用程序一样默认使用这些在线应用程序提供了一种方式。
其中registerContentHandler()方法接受三个参数:要处理的MIME类型、可以处理该MIME类型的页面的URL以及应用程序名称。
navigator.registerContentHandler(“application/rss+xml”,"#",“Some Reader”);
第一个参数是RSS源的MIME类型,第二个参数是应该接收RSS源URL的URL,其中的%s表示RSS源URL,由浏览器自动插入。当下一次请求RSS源时,浏览器就会打开指定的URL,而相应的Web应用程序将以适当方式来处理该请求。
类似的调用方式也适用于registerProtocolHandler()方法,接受三个参数:要处理的协议(比如mailto和ftp)、处理该协议的页面的URL和应用程序的名称。
navigator.registerProtocolHandler(“mailto”,"#",“Some Mail Client”);

4、screen对象

在这里插入图片描述

5、history对象

history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。因为history是window对象的属性,因此每个浏览器窗口、每个标签页乃至每个框架,都有自己的history对象与特定的window对象关联。出于安全方面的考虑,开发人员无法得知用户浏览过的URL。不过,借由用户访问过的页面列表,同样可以在不知道实际URL的情况下实现后退和前进。
使用history的go()方法可以在用户的历史记录中任意跳转,可以向前也可以向后。这个方法接受一个参数,表示向后或向前跳转的页面数的一个整数值,比如前进两页就是go(2),后退3页就是go(-3)。也可以接受一个字符串参数,此时浏览器会跳转到历史记录中包含该字符串的第一个位置——可能后退也可能前进,具体要看哪个位置更近。比如history.go(“wrox.com”)。
同时也可以使用back()和forward(),模拟浏览器前进或后退的按钮。
除了上述的方法外,history还有一个length属性保存了历史纪录的条数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值