十二

作者: xpwei | 来源:发表于2018-04-09 22:48 被阅读6次

    BOM
    window对象
    BOM的核心对象是window,它表示浏览器的一个实例。在浏览器中,window对象有双重角色,它既是通过JavaScript访问浏览器窗口的一个接口,又是ES规定的Global对象。这意味着在网页中定义的任何一个对象、变量和函数,都以window作为其Global对象,因此有权访问parseInt()等方法。

    全局作用域
    由于window对象同样扮演着ES中Global对象的角色,因此所有在全局作用域中声明的变量、函数都会变成window对象的属性和方法。
    抛开全局变量会成为window对象的属性不谈,定义全局变量与在window对象上直接定义属性还是有一点差别:全局变量不能通过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
    

    使用var语句添加的window属性有一个名为[[Configurable]]的特性,这个特性的值被设置为false,因此这样定义的属性不可以通过delete操作符删除。
    另外还要记住一件事:尝试访问未声明的变量会抛出错误,但是通过查询window对象,可以知道某个可能未声明的变量是否存在:

    //这里会抛出错误,因为oldValue未定义
    var newValue = oldValue;
    //这里不会抛出错误,因为这是一次属性查询
    //newValue 的值是undefined
    var newValue = window.oldValue;
    

    Windows Mobile平台的IE浏览器不允许通过window.property=value之类的形式,直接在window对象上创建新的属性或方法。可是,在全局作用域中声明的所有变量和函数,照样会变成window对象的成员。

    窗口关系及框架
    如果页面中包含框架,则每个框架都拥有自己的window对象,并且保存在frames集合中。在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>
    

    以上代码创建了一个框架集,其中一个框架居上,两个框架居下。可以通过window.frames[0]或者window.frames["topFrame"]来引用上方的框架。不过,恐怕你最好使用top而非window来引用这些框架(top.frames[0])。
    top对象始终指向最高(最外)层的框架,也就是浏览器窗口。使用它可以确保在一个框架中正确地访问另一个框架。因为对于在一个框架中编写的任何代码来说,其中的window对象指向的都是那个框架的特定实例,而非最高层的框架。
    与top相对的另一个window对象是parent。顾名思义,parent(父)对象始终指向当前框架的直接上层框架。在某些情况下,parent有可能等于top;但在没有框架的情况下,parent一定等于top(此时他们都等于window):
    上面代码框架集中的一个框架包含了另一个框架集:

    <html>
    <head>
        <title>Frameset Example</title>
    </head>
    <frameset cols="50%,50%">
        <frame src="red.htm" name="redFrame">
            <frame src="blue.htm" name="blueFrame">
    </frameset>
    </html>
    

    浏览器在加载完第一个框架集以后,会继续将第二个框架集加载到rightFrame中。如果代码位于redFrame(或blueFrame)中,那么parent对象指向的就是rightFrame。可是,如果代码位于topFrame中,则parent指向的是top,因为topFrame的直接上层框架就是最外层框架。
    与框架有关的最后一个对象是self,它始终指向window;实际上,self和window对象可以互换使用。引入self对象的目的只是为了与top和parent对象对应起来,因此它不格外包含其他值。
    所有这些对象都是window对象的属性,可以通过window.parent、window.top等形式来访问。同时,这也意味着可以将不同层次的window对象连缀起来,例如window.parent.parent.frames[0]。

    窗口位置
    用来确定和修改window对象位置的属性和方法有很多。IE、Safari、Opera 和 Chrome都提供了screenLeft和screenTop属性,分别用于表示窗口相对于屏幕左边和上边的位置。Firefox则再screenX和screenY属性中提供相同的窗口位置信息,Safari和Chrome也同时支持这两个属性。Opera虽然也支持screenX和screenY属性,但与screenLeft和screenTop属性并不对应,因此建议大家不要在Opera中使用它们。使用下拉代码可以跨浏览器取得窗口左边和上边的位置:

    var leftPos = (typeof window.screenLeft == "number") ?
        window.screenLeft : window.screenX;
    var topPos = (typeof window.screenTop == "number") ?
        window.screenTop : window.screenY;
    

    在使用这些值的过程中,还必须注意一些小问题。在IE、Opera中,screenLeft和screenTop中保存的是从屏幕左边和上边到由window对象表示的页面可见区域的距离。换句话说,如果window对象是最外层对象,而且浏览器窗口紧贴屏幕最上端——即y轴坐标为0,那么screenTop的值就是位于页面可见区域上方的浏览器工具栏的像素高度。但是,在Chrome、Firefox和Safari中,screenY或screenTop中保存的是整个浏览器窗口相对于屏幕的坐标值,即在窗口的y轴坐标为0时返回0。
    更让人捉摸不透的是,Firefox、Safari和Chrome始终返回页面中每个框架的top.screenX和top.screenY值。即使在页面由于被设置了外边距而发生偏移的情况下,相对于window对象使用screenX和screenY每次也都会返回相同的值。而IE和Opera则会给出框架相对于屏幕边界的精确坐标值。
    最终结果,就是无法再跨浏览器的条件下取得窗口左边和上边的精确坐标值。然而,使用moveTo()和moveBy()方法倒是有可能将窗口精确地移动到一个新位置:

    //将窗口移动到屏幕左上角
    window.moveTo(0,0);
    //将窗口向下移动100像素
    window.moveBy(0,100);
    //将窗口移动到(200,300)
    window.moveTo(200,300);
    //将窗口向左移动50像素
    window.moveBy(-50,0);
    

    需要注意的是,这两个方法可能会被浏览器禁用。而且,在Opera和IE7(及更高版本)中默认就是禁用的。另外,这两个方法不适用于框架,只能对最外层的window对象使用。

    窗口大小
    跨浏览器确定一个窗口的大小不是一件简单的事。IE9+、Firefox、Safari、Opera、Chrome均为此提供了4个属性:innerWidth、innerHeight、outerWidth 、outerHeight。在IE9+􀇋Safari 􀖖 Firefox中,outerWidth 􀖖 outerHeight返回浏览器窗口本身的尺寸(无论是从最外层的window对象还是从某个框架访问)。在Opera中,这两个属性的值表示页面视图容器的大小。而innerWidth 􀖖 innerHeight则表示该容器中页面视图去的大小(减去边框宽度)。在Chrome中,outerWidth􀇋outerHeight与innerWidth􀇋innerHeight返回相同的值,即视口(viewport)大小而非浏览器窗口大小。
    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,
        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;
        }
    }
    

    对于移动设备,window.innerWidth 􀖖 window.innerHeight保存着可见视口,也就是屏幕上可见页面区域的大小。移动IE浏览器不支持这些属性,但通过document.documentElement.client-
    Width 􀖖 document.documentElement.clientHeihgt提供了相同的信息。随着页面的缩放,这些值也会相应变化。
    在其他移动浏览器中,document.documentElement度量的是布局视口,即渲染后页面的实际大小(与可见视口不同,可见视口只是整个页面中的一小部分)。移动IE浏览器把布局视口的信息保存在document.body.clientWidth 􀖖document.body.clientHeight中。这些值不会随页面缩放而变化。
    另外,使用resizeTo()􀖖 resizeBy()方法可以调整浏览器窗口的大小:

    //调整到 100x100
    window.resizeTo(100, 100);
    //调整到200x150
    window.resizeBy(100, 50);
    //调整到 300x300
    window.resizeTo(300, 300);
    

    注意,这两个方法在Opera和IE7+中默认是禁用的。另外,这两个方法同样不适用于框架,而只能对最外层的window对象使用。

    相关文章

      网友评论

          本文标题:十二

          本文链接:https://www.haomeiwen.com/subject/rgjwhftx.html