window

作者: 竹杠敲头 | 来源:发表于2020-08-11 11:32 被阅读0次

    概述

    浏览器里面,window对象(注意,w为小写)指当前的浏览器窗口。它也是当前页面的顶层对象,即最高一层的对象,所有其他对象都是它的下属。一个变量如果未声明,那么默认就是顶层对象的属性。

    a = 1;
    window.a // 1
    

    上面代码中,a是一个没有声明就直接赋值的变量,它自动成为顶层对象的属性。

    window有自己的实体含义,其实不适合当作最高一层的顶层对象,这是一个语言的设计失误。最早,设计这门语言的时候,原始设想是语言内置的对象越少越好,这样可以提高浏览器的性能。因此,语言设计者 Brendan Eich 就把window对象当作顶层对象,所有未声明就赋值的变量都自动变成window对象的属性。这种设计使得编译阶段无法检测出未声明变量,但到了今天已经没有办法纠正了。

    window对象属性

    1.window.name

    window.name属性是一个字符串,表示当前浏览器窗口的名字。窗口不一定需要名字,这个属性主要配合超链接和表单的target属性使用。

    window.name = 'Hello World!';
    console.log(window.name)
    // "Hello World!"
    

    该属性只能保存字符串,如果写入的值不是字符串,会自动转成字符串。各个浏览器对这个值的储存容量有所不同,但是一般来说,可以高达几MB。

    只要浏览器窗口不关闭,这个属性是不会消失的。举例来说,访问a.com时,该页面的脚本设置了window.name,接下来在同一个窗口里面载入了b.com,新页面的脚本可以读到上一个网页设置的window.name。页面刷新也是这种情况。一旦浏览器窗口关闭后,该属性保存的值就会消失,因为这时窗口已经不存在了。


    2.window.closed,window.opener

    window.closed返回一个布尔值,表示当前窗口是否已经关闭。
    上面代码检查当前窗口是否关闭。这种检查意义不大,因为只要能运行代码,当前窗口肯定没有关闭。这个属性一般用来检查,使用脚本打开的新窗口是否关闭。

    ar popup = window.open();
    
    if ((popup !== null) && !popup.closed) {
      // 窗口仍然打开着
    }
    

    window.opener属性表示打开当前窗口的父窗口。如果当前窗口没有父窗口(即直接在地址栏输入打开),则返回null。

    window.open().opener === window // true
    

    上面表达式会打开一个新窗口,然后返回true。

    如果两个窗口之间不需要通信,建议将子窗口的opener属性显式设为null,这样可以减少一些安全隐患。

    var newWin = window.open('example.html', 'newWindow', 'height=400,width=400');
    newWin.opener = null;
    

    上面代码中,子窗口的opener属性设为null,两个窗口之间就没办法再联系了。

    通过opener属性,可以获得父窗口的全局属性和方法,但只限于两个窗口同源的情况,且其中一个窗口由另一个打开。<a>元素添加rel="noopener"属性,可以防止新打开的窗口获取父窗口,减轻被恶意网站修改父窗口 URL 的风险。

    <a href="https://an.evil.site" target="_blank" rel="noopener">
    恶意网站
    </a>
    

    3.window.self,window.window

    window.self和window.window都指向当前窗口

    window.window === window; //true
    window.self = window; //true
    

    4.window.frames,window.length

    window.frames返回一个类似数组的对象,成员由当前页面所包含的框架结构构成,包含了frame和iframe。window.frames[0]可以获取页面第一个窗口结构。
    如果iframe设置了id或者name属性,我们可以通过属性来获取窗口。如<iframe name="iframeName" />name可以通过window.iframes['iframeName']来获取,或者frames.iframeName。

    某种程度上来讲,frames其实上就是一个window对象。

    frames === window; //true
    

    所以我们frames[0]也可以直接使用window[0]来表示。但是从语义上来讲,frames更加确切一些,而且window是全局对象,容易搞混,因此推荐使用frames来表达。


    window.length表示当前网页包含的框架数量,如果页面不包含frame或者iframe元素,则返回0

    window.frames.length === window.length; //true
    

    从上面代码也可以看出来frames其实也就是window

    5.window.frameElement

    window.frameElement主要应用于一个页面嵌套在另一个页面的情况。(<object>、<frame>、<embed>),返回当前元素所在的那个页面节点,如果当前页面时顶层,或者所嵌入的不是同源(非同一资源下的页面)的,则返回null。

    //在index.html中
    <frame src="b.html">
    //在b.html中
    const frameB = window.frameElement;
    if(frameB){
        frameB .src = 'v.html';  
    }
    

    以上frameB指的就是frame。

    6.window.top和window.parent

    window.top指的是当前页面的最顶层框架,主要用于frame框架页面中。
    window.parent指的是当前框架的父框架

    window.top === window.parent;
    

    以上方法可以用来判断是否是多层嵌套的页面。

    7.window.status

    window.status主要用于读写浏览器状态栏的内容。但是现在大部分浏览器是不允许修改的,所以基本没什么用。

    8.window.devicePixelRatio

    window.devicePixelRatio返回一个数值,表示css像素大小与显示器物理像素的一个比例。也就是表示css像素由多少个物理像素构成。
    它可以用来表示用户显示器的显示效果,也就是说这个数值越大,表示用户用的越是高清显示器,我们便可以使用高像素的照片或者视频。

    9.位置信息

    以下返回window的大小及位置信息

    (1)window.screenX和window.screenY

    window.screenX和window.screenY返回浏览器窗口相对于显示器左上角的水平距离和垂直距离。这两个属性都是只读属性。

    (2)window.innerWith和window.innerHeight

    window.innerWith和window.innerHeight返回当前网页在在窗口中可见部分的大小,即视口(viewport)的大小,也是只读属性

    (3)window.outerWith和window.outerHeight

    window.outerWith和window.outerHeight返回当前浏览器窗口的大小,包括浏览器的任务栏及边框等。也是只读属性。

    (4)window.scrollX和window.scrollY

    window.scrollX和window.scrollY返回当前网页的水平和垂直感动距离,单位都是像素,且是只读属性。

    这两个属性返回的是双精度浮点数,并不是整数,如果页面没有滚动,则返回0.

    (5)window.pageXOffset,window.pageYOffset

    window.pageXOffset,window.pageYOffset是window.scrollX和window.scrollY的别名,用法一致。

    window属性

    window.locationbar:地址栏对象
    window.menubar:菜单栏对象
    window.scrollbars:窗口的滚动条对象
    window.toolbar:工具栏对象
    window.statusbar:状态栏对象
    window.personalbar:用户安装的个人工具栏对象
    这些属性的visible属性表示这些属性是否可见,都是只读属性。

    window.locationbar.visible
    window.menubar.visible
    window.scrollbars.visible
    window.toolbar.visible
    window.statusbar.visible
    window.personalbar.visible
    

    全局对象属性

    • window.document对象,即document对象。这个属性有同源限制,只有同源的属性才能读取这个属性
    • window.location对象,即location对象,用来获取网页URL的相关信息,等同于document.location。
    • window.navigator,指向Navigator对象,用于获取环境信息。
    • window.history,指向History对象,用于获取浏览器的浏览历史
    • window.localStorage,指向浏览器本地存储localStorage数据对象。
    • window.sessionStorage,指向本地存储的sessionStorage数据对象。
    • window.console,指向sonsole对象,用于操作控制台。
    • window.screen,获取当前屏幕的信息。

    window.isSecureContext

    用于判断当前窗口是否属于加密环境,返回一个Boolean值。如果是https返回true,http返回false。

    window的方法

    window.alert()、window.prompt()、window.confirm()都是浏览器与用户互动的全局方法。它们会弹出不同的对话框,要求用户做出回应。注意,这三个方法弹出的对话框,都是浏览器统一规定的式样,无法定制。也可以省去window,直接嗲用方法。
    这三个方法都具有堵塞效应,一旦弹出对话框,整个页面就是暂停执行,等待用户做出反应。

    window.alert('hello')
    

    window.alert()方法弹出的对话框,只有一个“确定”按钮,往往用来通知用户某些信息。
    用户只有点击“确定”按钮,对话框才会消失。对话框弹出期间,浏览器窗口处于冻结状态,如果不点“确定”按钮,用户什么也干不了。
    window.alert()方法的参数只能是字符串,没法使用 CSS 样式,但是可以用\n指定换行。

    var result = prompt('您的年龄?', 25)
    

    window.prompt()方法弹出的对话框,提示文字的下方,还有一个输入框,要求用户输入信息,并有“确定”和“取消”两个按钮。它往往用来获取用户输入的数据。
    上面代码会跳出一个对话框,文字提示为“您的年龄?”,要求用户在对话框中输入自己的年龄(默认显示25)。用户填入的值,会作为返回值存入变量result。
    window.prompt()的返回值有两种情况,可能是字符串(有可能是空字符串),也有可能是null。具体分成三种情况。
    用户输入信息,并点击“确定”,则用户输入的信息就是返回值。
    用户没有输入信息,直接点击“确定”,则输入框的默认值就是返回值。
    用户点击了“取消”(或者按了 ESC 按钮),则返回值是null。
    window.prompt()方法的第二个参数是可选的,但是最好总是提供第二个参数,作为输入框的默认值。

    var result = confirm('你最近好吗?');
    var okay = confirm('Please confirm this message.');
    if (okay) {
      // 用户按下“确定”
    } else {
      // 用户按下“取消”
    }
    

    window.confirm()方法弹出的对话框,除了提示信息之外,只有“确定”和“取消”两个按钮,往往用来征询用户是否同意。
    上面代码弹出一个对话框,上面只有一行文字“你最近好吗?”,用户选择点击“确定”或“取消”。
    confirm方法返回一个布尔值,如果用户点击“确定”,返回true;如果用户点击“取消”,则返回false。
    confirm的一个用途是,用户离开当前页面时,弹出一个对话框,问用户是否真的要离开。

    window的操作事件

    window.open方法用于新建另一个浏览器窗口,类似于浏览器菜单的新建窗口选项。它会返回新窗口的引用,如果无法新建窗口,则返回null。

    window.open();

    var popup = window.open('somefile.html');
    

    上面代码会让浏览器弹出一个新建窗口,网址是当前域名下的somefile.html。
    open方法一共可以接受三个参数。

    • url:字符串,表示新窗口的网址。如果省略,默认网址就是about:blank。
    • windowName:字符串,表示新窗口的名字。如果该名字的窗口已经存在,则占用该窗口,不再新建窗口。如果省略,就默认使用_blank,表示新建一个没有名字的窗口。另外还有几个预设值,_self表示当前窗口,_top表示顶层窗口,_parent表示上一层窗口。
    • windowFeatures:字符串,内容为逗号分隔的键值对(详见下文),表示新窗口的参数,比如有没有提示栏、工具条等等。如果省略,则默认打开一个完整 UI 的新窗口。如果新建的是一个已经存在的窗口,则该参数不起作用,浏览器沿用以前窗口的参数。
    var popup = window.open(
      'somepage.html',
      'DefinitionsWindows',
      'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
    );
    

    如上,是一个比较完整的例子。
    第三个参数可以使用的参数:

    • left:新窗口距离屏幕最左边的距离(单位像素)。注意,新窗口必须是可见的,不能设置在屏幕以外的位置。
    • top:新窗口距离屏幕最顶部的距离(单位像素)。
    • height:新窗口内容区域的高度(单位像素),不得小于100。
    • width:新窗口内容区域的宽度(单位像素),不得小于100。
    • outerHeight:整个浏览器窗口的高度(单位像素),不得小于100。
    • outerWidth:整个浏览器窗口的宽度(单位像素),不得小于100。
    • menubar:是否显示菜单栏。
    • toolbar:是否显示工具栏。
    • location:是否显示地址栏。
    • personalbar:是否显示用户自己安装的工具栏。
    • status:是否显示状态栏。
    • dependent:是否依赖父窗口。如果依赖,那么父窗口最小化,该窗口也最小化;父窗口关闭,该窗口也关闭。
    • minimizable:是否有最小化按钮,前提是dialog=yes。
    • noopener:新窗口将与父窗口切断联系,即新窗口的window.opener属性返回null,父窗口的window.open()方法也返回null。
    • resizable:新窗口是否可以调节大小。
    • scrollbars:是否允许新窗口出现滚动条。
    • dialog:新窗口标题栏是否出现最大化、最小化、恢复原始大小的控件。
    • titlebar:新窗口是否显示标题栏。
    • alwaysRaised:是否显示在所有窗口的顶部。
    • alwaysLowered:是否显示在父窗口的底下。
    • close:新窗口是否显示关闭按钮。

    对于那些可以打开和关闭的属性,设为yes或1或不设任何值就表示打开,比如status=yes、status=1、status都会得到同样的结果。如果想设为关闭,不用写no,而是直接省略这个属性即可。也就是说,如果在第三个参数中设置了一部分属性,其他没有被设置的yes/no属性都会被设成no,只有titlebar和关闭按钮除外(它们的值默认为yes)。

    另外,open()方法的第二个参数虽然可以指定已经存在的窗口,但是不等于可以任意控制其他窗口。为了防止被不相干的窗口控制,浏览器只有在两个窗口同源,或者目标窗口被当前网页打开的情况下,才允许open方法指向该窗口。

    window.open方法返回新窗口的引用。

    var windowB = window.open('windowB.html', 'WindowB');
    windowB.window.name // "WindowB"
    

    注意,如果新窗口和父窗口不是同源的(即不在同一个域),它们彼此不能获取对方窗口对象的内部属性。

    下面是另一个例子。

    var w = window.open();
    console.log('已经打开新窗口');
    w.location = 'http://example.com';
    

    上面代码先打开一个新窗口,然后在该窗口弹出一个对话框,再将网址导向example.com。

    由于open这个方法很容易被滥用,许多浏览器默认都不允许脚本自动新建窗口。只允许在用户点击链接或按钮时,脚本做出反应,弹出新窗口。因此,有必要检查一下打开新窗口是否成功。

    var popup = window.open();
    if (popup === null) {
      // 新建窗口失败
    }
    

    window.close();

    window.close方法用于关闭当前窗口,一般只用来关闭window.open方法新建的窗口。

    popup.close()
    

    该方法只对顶层窗口有效,iframe框架之中的窗口使用该方法无效。


    window.stop()

    window.stop()方法完全等同于单击浏览器的停止按钮,会停止加载图像、视频等正在或等待加载的对象。

    window.stop()
    

    window.moveTo(),window.moveBy()

    window.moveTo()方法用于移动浏览器窗口到指定位置。它接受两个参数,分别是窗口左上角距离屏幕左上角的水平距离和垂直距离,单位为像素。

    window.moveTo(100, 200)
    

    上面代码将窗口移动到屏幕(100, 200)的位置。

    window.moveBy()方法将窗口移动到一个相对位置。它接受两个参数,分别是窗口左上角向右移动的水平距离和向下移动的垂直距离,单位为像素。

    window.moveBy(25, 50)
    

    上面代码将窗口向右移动25像素、向下移动50像素。

    为了防止有人滥用这两个方法,随意移动用户的窗口,目前只有一种情况,浏览器允许用脚本移动窗口:该窗口是用window.open()方法新建的,并且窗口里只有它一个 Tab 页。除此以外的情况,使用上面两个方法都是无效的。


    window.resizeTo(),window.resizeBy()

    window.resizeTo()方法用于缩放窗口到指定大小。

    它接受两个参数,第一个是缩放后的窗口宽度(outerWidth属性,包含滚动条、标题栏等等),第二个是缩放后的窗口高度(outerHeight属性)。

    window.resizeTo(
      window.screen.availWidth / 2,
      window.screen.availHeight / 2
    )
    

    上面代码将当前窗口缩放到,屏幕可用区域的一半宽度和高度。

    window.resizeBy()方法用于缩放窗口。它与window.resizeTo()的区别是,它按照相对的量缩放,window.resizeTo()需要给出缩放后的绝对大小。

    它接受两个参数,第一个是水平缩放的量,第二个是垂直缩放的量,单位都是像素。

    window.resizeBy(-200, -200)
    

    上面的代码将当前窗口的宽度和高度,都缩小200像素。


    window.scrollTo(),window.scroll(),window.scrollBy()

    window.scrollTo方法用于将文档滚动到指定位置。它接受两个参数,表示滚动后位于窗口左上角的页面坐标。

    window.scrollTo(x-coord, y-coord)
    

    它也可以接受一个配置对象作为参数。

    window.scrollTo(options)
    

    配置对象options有三个属性。

    • top:滚动后页面左上角的垂直坐标,即 y 坐标。
    • left:滚动后页面左上角的水平坐标,即 x 坐标。
    • behavior:字符串,表示滚动的方式,有三个可能值(smooth、instant、auto),默认值为auto。
      top: 1000,
      behavior: 'smooth'
    });
    
    

    window.scroll()方法是window.scrollTo()方法的别名。

    window.scrollBy()方法用于将网页滚动指定距离(单位像素)。它接受两个参数:水平向右滚动的像素,垂直向下滚动的像素。

    window.scrollBy(0, window.innerHeight)
    

    上面代码用于将网页向下滚动一屏。

    如果不是要滚动整个文档,而是要滚动某个元素,可以使用下面三个属性和方法。

    Element.scrollTop
    Element.scrollLeft
    Element.scrollIntoView()
    window.print()
    

    window.print方法会跳出打印对话框,与用户点击菜单里面的“打印”命令效果相同。

    常见的打印按钮代码如下。

    document.getElementById('printLink').onclick = function () {
      window.print();
    }
    

    非桌面设备(比如手机)可能没有打印功能,这时可以这样判断。

      // 支持打印功能
    }
    

    window.focus(),window.blur()

    window.focus()方法会激活窗口,使其获得焦点,出现在其他窗口的前面。

    var popup = window.open('popup.html', 'Popup Window');
    
    if ((popup !== null) && !popup.closed) {
      popup.focus();
    }
    

    上面代码先检查popup窗口是否依然存在,确认后激活该窗口。

    window.blur()方法将焦点从窗口移除。

    当前窗口获得焦点时,会触发focus事件;当前窗口失去焦点时,会触发blur事件。


    window.getSelection()

    window.getSelection方法返回一个Selection对象,表示用户现在选中的文本。

    var selObj = window.getSelection();
    使用Selection对象的toString方法可以得到选中的文本。

    var selectedText = selObj.toString();
    window.getComputedStyle(),window.matchMedia()
    

    window.getComputedStyle()方法接受一个元素节点作为参数,返回一个包含该元素的最终样式信息的对象。

    window.matchMedia()方法用来检查 CSS 的mediaQuery语句。


    window.requestAnimationFrame()

    window.requestAnimationFrame()方法跟setTimeout类似,都是推迟某个函数的执行。不同之处在于,setTimeout必须指定推迟的时间,window.requestAnimationFrame()则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16ms 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,requestAnimationFrame()会暂停执行。

    如果某个函数会改变网页的布局,一般就放在window.requestAnimationFrame()里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。

    该方法接受一个回调函数作为参数。

    window.requestAnimationFrame(callback)
    

    上面代码中,callback是一个回调函数。callback执行时,它的参数就是系统传入的一个高精度时间戳(performance.now()的返回值),单位是毫秒,表示距离网页加载的时间。

    window.requestAnimationFrame()的返回值是一个整数,这个整数可以传入window.cancelAnimationFrame(),用来取消回调函数的执行。

    下面是一个window.requestAnimationFrame()执行网页动画的例子。

    var element = document.getElementById('animate');
    element.style.position = 'absolute';
    
    var start = null;
    
    function step(timestamp) {
      if (!start) start = timestamp;
      var progress = timestamp - start;
      // 元素不断向左移,最大不超过200像素
      element.style.left = Math.min(progress / 10, 200) + 'px';
      // 如果距离第一次执行不超过 2000 毫秒,
      // 就继续执行动画
      if (progress < 2000) {
        window.requestAnimationFrame(step);
      }
    }
    
    window.requestAnimationFrame(step);
    

    上面代码定义了一个网页动画,持续时间是2秒,会让元素向右移动。


    window.requestIdleCallback()

    window.requestIdleCallback()跟setTimeout类似,也是将某个函数推迟执行,但是它保证将回调函数推迟到系统资源空闲时执行。也就是说,如果某个任务不是很关键,就可以使用window.requestIdleCallback()将其推迟执行,以保证网页性能。

    它跟window.requestAnimationFrame()的区别在于,后者指定回调函数在下一次浏览器重排时执行,问题在于下一次重排时,系统资源未必空闲,不一定能保证在16毫秒之内完成;window.requestIdleCallback()可以保证回调函数在系统资源空闲时执行。

    该方法接受一个回调函数和一个配置对象作为参数。配置对象可以指定一个推迟执行的最长时间,如果过了这个时间,回调函数不管系统资源有无空虚,都会执行。

    window.requestIdleCallback(callback[, options])
    

    callback参数是一个回调函数。该回调函数执行时,系统会传入一个IdleDeadline对象作为参数。IdleDeadline对象有一个didTimeout属性(布尔值,表示是否为超时调用)和一个timeRemaining()方法(返回该空闲时段剩余的毫秒数)。

    options参数是一个配置对象,目前只有timeout一个属性,用来指定回调函数推迟执行的最大毫秒数。该参数可选。

    window.requestIdleCallback()方法返回一个整数。该整数可以传入window.cancelIdleCallback()取消回调函数。

    下面是一个例子。

    requestIdleCallback(myNonEssentialWork);
    
    function myNonEssentialWork(deadline) {
      while (deadline.timeRemaining() > 0) {
        doWorkIfNeeded();
      }
    }
    

    上面代码中,requestIdleCallback()用来执行非关键任务myNonEssentialWork。该任务先确认本次空闲时段有剩余时间,然后才真正开始执行任务。

    下面是指定timeout的例子。

    requestIdleCallback(processPendingAnalyticsEvents, { timeout: 2000 });
    

    上面代码指定,processPendingAnalyticsEvents必须在未来2秒之内执行。

    如果由于超时导致回调函数执行,则deadline.timeRemaining()返回0,deadline.didTimeout返回true。

    如果多次执行window.requestIdleCallback(),指定多个回调函数,那么这些回调函数将排成一个队列,按照先进先出的顺序执行。

    load 事件和 onload 属性

    load事件发生在文档在浏览器窗口加载完毕时。window.onload属性可以指定这个事件的回调函数。

    window.onload = function() {
      var elements = document.getElementsByClassName('example');
      for (var i = 0; i < elements.length; i++) {
        var elt = elements[i];
        // ...
      }
    };
    

    error 事件和 onerror 属性

    浏览器脚本发生错误时,会触发window对象的error事件。我们可以通过window.onerror属性对该事件指定回调函数。

    window.onerror = function (message, filename, lineno, colno, error) {
      console.log("出错了!--> %s", error.stack);
    };
    

    由于历史原因,window的error事件的回调函数不接受错误对象作为参数,而是一共可以接受五个参数,它们的含义依次如下。

    • 出错信息
    • 出错脚本的网址
    • 行号
    • 列号
    • 错误对象

    老式浏览器只支持前三个参数。
    并不是所有的错误,都会触发 JavaScript 的error事件(即让 JavaScript 报错)。一般来说,只有 JavaScript 脚本的错误,才会触发这个事件,而像资源文件不存在之类的错误,都不会触发。
    下面是一个例子,如果整个页面未捕获错误超过3个,就显示警告。

    window.onerror = function(msg, url, line) {
      if (onerror.num++ > onerror.max) {
        alert('ERROR: ' + msg + '\n' + url + ':' + line);
        return true;
      }
    }
    onerror.max = 3;
    onerror.num = 0;
    

    需要注意的是,如果脚本网址与网页网址不在同一个域(比如使用了 CDN),浏览器根本不会提供详细的出错信息,只会提示出错,错误类型是“Script error.”,行号为0,其他信息都没有。这是浏览器防止向外部脚本泄漏信息。一个解决方法是在脚本所在的服务器,设置Access-Control-Allow-Origin的 HTTP 头信息。

    Access-Control-Allow-Origin: *
    

    然后,在网页的<script>标签中设置crossorigin属性。

    <script crossorigin="anonymous" src="//example.com/file.js"></script>
    

    上面代码的crossorigin="anonymous"表示,读取文件不需要身份信息,即不需要 cookie 和 HTTP 认证信息。如果设为crossorigin="use-credentials",就表示浏览器会上传 cookie 和 HTTP 认证信息,同时还需要服务器端打开 HTTP 头信息Access-Control-Allow-Credentials。


    window 对象的事件监听属性

    除了具备元素节点都有的 GlobalEventHandlers 接口,window对象还具有以下的事件监听函数属性。

    • window.onafterprint:afterprint事件的监听函数。
    • window.onbeforeprint:beforeprint事件的监听函数。
    • window.onbeforeunload:beforeunload事件的监听函数。
    • window.onhashchange:hashchange事件的监听函数。
    • window.onlanguagechange: languagechange的监听函数。
    • window.onmessage:message事件的监听函数。
    • window.onmessageerror:MessageError事件的监听函数。
    • window.onoffline:offline事件的监听函数。
    • window.ononline:online事件的监听函数。
    • window.onpagehide:pagehide事件的监听函数。
    • window.onpageshow:pageshow事件的监听函数。
    • window.onpopstate:popstate事件的监听函数。
    • window.onstorage:storage事件的监听函数。
    • window.onunhandledrejection:未处理的 Promise 对象的reject事件的监听函数。
    • window.onunload:unload事件的监听函数。

    多窗口操作

    由于网页可以使用iframe元素,嵌入其他网页,因此一个网页之中会形成多个窗口。如果子窗口之中又嵌入别的网页,就会形成多级窗口。

    窗口的引用

    各个窗口之中的脚本,可以引用其他窗口。浏览器提供了一些特殊变量,用来返回其他窗口。

    • window.top:顶层窗口,即最上层的那个窗口
    • window.parent:父窗口
    • window.self:当前窗口,即自身
      下面代码可以判断,当前窗口是否为顶层窗口。
    if (window.top === window.self) {
      // 当前窗口是顶层窗口
    } else {
      // 当前窗口是子窗口
    }
    

    下面的代码让父窗口的访问历史后退一次。

    window.parent.history.back();
    

    与这些变量对应,浏览器还提供一些特殊的窗口名,供window.open()方法、<a>标签、<form>标签等引用。
    _top:顶层窗口
    _parent:父窗口
    _blank:新窗口
    下面代码就表示在顶层窗口打开链接。

    <a href="somepage.html" target="_top">Link</a>
    

    iframe 元素

    对于iframe嵌入的窗口,document.getElementById方法可以拿到该窗口的 DOM 节点,然后使用contentWindow属性获得iframe节点包含的window对象。

    var frame = document.getElementById('theFrame');
    var frameWindow = frame.contentWindow;
    

    上面代码中,frame.contentWindow可以拿到子窗口的window对象。然后,在满足同源限制的情况下,可以读取子窗口内部的属性。

    // 获取子窗口的标题
    frameWindow.title
    <iframe>元素的contentDocument属性,可以拿到子窗口的document对象。

    var frame = document.getElementById('theFrame');
    var frameDoc = frame.contentDocument;
    
    // 等同于
    var frameDoc = frame.contentWindow.document;
    

    <iframe>元素遵守同源政策,只有当父窗口与子窗口在同一个域时,两者之间才可以用脚本通信,否则只有使用window.postMessage方法。

    <iframe>窗口内部,使用window.parent引用父窗口。如果当前页面没有父窗口,则window.parent属性返回自身。因此,可以通过window.parent是否等于window.self,判断当前窗口是否为iframe窗口。

    if (window.parent !== window.self) {
      // 当前窗口是子窗口
    }
    

    <iframe>窗口的window对象,有一个frameElement属性,返回<iframe>在父窗口中的 DOM 节点。对于非嵌入的窗口,该属性等于null。

    var f1Element = document.getElementById('f1');
    var f1Window = f1Element.contentWindow;
    
    f1Window.frameElement === f1Element // true
    window.frameElement === null // true
    

    window.frames 属性

    window.frames属性返回一个类似数组的对象,成员是所有子窗口的window对象。可以使用这个属性,实现窗口之间的互相引用。比如,frames[0]返回第一个子窗口,frames[1].frames[2]返回第二个子窗口内部的第三个子窗口,parent.frames[1]返回父窗口的第二个子窗口。

    注意,window.frames每个成员的值,是框架内的窗口(即框架的window对象),而不是iframe标签在父窗口的 DOM 节点。如果要获取每个框架内部的 DOM 树,需要使用window.frames[0].document的写法。

    另外,如果<iframe>元素设置了name或id属性,那么属性值会自动成为全局变量,并且可以通过window.frames属性引用,返回子窗口的window对象。

    // HTML 代码为 <iframe id="myFrame">
    window.myFrame // [HTMLIFrameElement]
    frames.myframe === myFrame // true
    

    另外,name属性的值会自动成为子窗口的名称,可以用在window.open方法的第二个参数,或者<a>和<frame>标签的target属性。

    完结,撒花

    相关文章

      网友评论

          本文标题:window

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