window对象-iframe

参考文献:

a 标签onclick 和 href冲突

frame VS iframe

w3c已经不推荐使用frame,而推荐使用iframeiframe也就是inline frame(行内frame),顾名思义它具有css的行内框特性,正是因为这一特性才引出来iframe 高度100%时,出现垂直滚动条。

frame相关window属性

window.frames

window.frames属性返回一个类似数组的对象,成员为页面内所有框架窗口,包括frame元素和iframe元素。window.frames[0]表示页面中第一个框架窗口。

如果iframe元素设置了idname属性,那么就可以用属性值,引用这个iframe窗口。比如<iframe name="myIFrame">可以用frames['myIFrame']或者frames.myIFrame来引用。

frames属性实际上是window对象的别名。

js 复制代码
frames === window // true

因此,frames[0]也可以用window[0]表示。但是,从语义上看,frames更清晰,而且考虑到window还是全局对象,因此推荐表示多窗口时,总是使用frames[0]的写法。

window.length

window.length属性返回当前网页包含的框架总数。如果当前网页不包含frameiframe元素,那么window.length就返回0

js 复制代码
window.frames.length === window.length // true

上面代码表示,window.frames.lengthwindow.length应该是相等的。

window.frameElement

window.frameElement属性主要用于当前窗口嵌在另一个网页的情况(嵌入<object><iframe><embed>元素),返回当前窗口所在的那个元素节点 。如果当前窗口是顶层窗口,或者所嵌入的那个网页不是同源的,该属性返回null

js 复制代码
// HTML 代码如下
// <iframe src="about.html"></iframe>

// 下面的脚本在 about.html 里面
var frameEl = window.frameElement;
if (frameEl) {
  frameEl.src = 'other.html';
}

上面代码中,frameEl变量就是<iframe>元素。

iframe相关获取

通过window获取iframe

window.frames是个伪数组,可以通过window.frames[index]window.frames[name]来获取iframe

  • window.frames[index],索引是从左往右,从上往下的,从0开始,
  • 通常我们使用window.frames[name]来获取iframe

通过iframe获取window、document

如果想获取iframe里的window或者document,可以使用

  • iframe.contentWindow
  • iframe.contentDocument

iframe.contentDocument=iframe.contentWindow.document,不过iframe.contentDocument在IE8及以下的版本不支持。

如何调用iframe中的方法

如果想调用iframe中的方法,可以按照以下步骤:

(1)在父页面中获取iframe元素的引用

js 复制代码
let iframe = document.getElementById('iframeId')

(2)通过iframecontentWindow属性获取到iframe中的window对象

js 复制代码
let iframeWindow = iframe.contentWindow

(3)接着就可以调用iframe中定义的方法了

js 复制代码
iframeWindow.methodName()

调用跨域iframe中的方法需要在两个页面之间建立信任关系,具体可以参考跨域通信相关知识。

多窗口操作

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

窗口的引用

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

  • top:顶层窗口,即最上层的那个窗口
  • parent:父窗口
  • self:当前窗口,即自身

下面代码可以判断,当前窗口是否为顶层窗口。

js 复制代码
if (window.top === window.self) {
  // 当前窗口是顶层窗口
} else {
  // 当前窗口是子窗口
}

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

js 复制代码
window.parent.history.back();

与这些变量对应,浏览器还提供一些特殊的窗口名,供window.open()方法、<a>标签、<form>标签等引用。

  • _top:顶层窗口
  • _parent:父窗口
  • _blank:新窗口

下面代码就表示在顶层窗口打开链接。

html 复制代码
<a href="somepage.html" target="_top">Link</a>

iframe元素

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

js 复制代码
var frame = document.getElementById('theFrame');
var frameWindow = frame.contentWindow;

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

js 复制代码
// 获取子窗口的标题
frameWindow.title

<iframe>元素的contentDocument属性,可以拿到子窗口的document对象。

js 复制代码
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窗口

javascript 复制代码
if (window.parent !== window.self) {
  // 当前窗口是子窗口
}

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

ini 复制代码
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]返回父窗口的第二个子窗口。

js 复制代码
// renderTableData为绑定在iframe窗口的window上的方法
  if (window.frames?.[iframeName]?.renderTableData) {
    window.frames[iframeName].renderTableData();
  }

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

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

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

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

window获取顶级窗口、父窗口

  • 获取顶级窗口:window.top
  • 获取父级窗口:window.parent
  • 导航栏回退:history.back(); 注意回退的请求,会有缓存。
  • 前进:history.forward()

history.back()和history.forward()仅仅是为了方便分别代替history.go(-1)和history.go(1)

相关推荐
前端小巷子25 分钟前
Web开发中的文件上传
前端·javascript·面试
翻滚吧键盘1 小时前
{{ }}和v-on:click
前端·vue.js
上单带刀不带妹1 小时前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
前端风云志1 小时前
typescript结构化类型应用两例
javascript
杨进军2 小时前
React 创建根节点 createRoot
前端·react.js·前端框架
ModyQyW2 小时前
用 AI 驱动 wot-design-uni 开发小程序
前端·uni-app
说码解字2 小时前
Kotlin lazy 委托的底层实现原理
前端
gnip2 小时前
总结一期正则表达式
javascript·正则表达式
爱分享的程序员3 小时前
前端面试专栏-算法篇:18. 查找算法(二分查找、哈希查找)
前端·javascript·node.js
翻滚吧键盘3 小时前
vue 条件渲染(v-if v-else-if v-else v-show)
前端·javascript·vue.js