关于frames的笔记
04 Nov 2017最近工作需求需要,用到了iframe,由于页面之间没有跨域,所以js写起来还算顺畅,不过在给同事讲postMessage
的使用时,遇到了一个使用问题,导致自己以为子页面iframe之间不能通过postMessage通信,只能通过子A传父,父再传子B的形式来实现A和B通信,然而静下心来发现,其实是自己用错了方式。
遇到的问题
iframe其实是个很棒的技术支持,详见».
起初遇到的问题是,一个页面里有两个iframe(A和B),通过postMessage的使用方式:
结果页面报跨域错误(几个页面不在同一个域上),当时也纳闷,postMessage不是支持跨域么?
而后,改成
居然就可以了。当时直接就打印一下frames[id]
和frames[index]
,发现不是同一个内容,前一个返回的是,iframe元素DOM,而后者则是返回iframe的window。
所以这是怎么回事呢?
window.frames
既然说到了一个知识点概念,那么就要祭出MDN文档了.
文档中提及的window.frames
主要有三个特点:
- 它是一个frame对象的列表类数组对象,具有length属性表示frame个数,以及可以通过下标方式访问到frame
- 它总是全等于当前window对象(注意点)
- 它以下标访问的数组元素,表示
<frame>
或<iframe>
的内容,而不是标签DOM元素,即相当于document.getElementsByTagName( "iframe" )[ 0 ].contentWindow
留意后两点,当我们用frames[index]
得到的是frame页面的window对象,而当我们用frames[id]
的方式,实际上访问的是当前window对象的id对应的属性,这是个啥呢?
可以查看这里描述, 当给dom赋值id之后,可通过window[id]
的方式直接访问到dom,于是frames[id]
就访问到了当前window里的id对应的dom,也就是iframe DOM。
window.frameElement
关于这个属性,是我遇到的另一个问题,就是我只知道当前页面A是以iframe的形式嵌入父页面B,我想在iframe的js里将自己作为iframe的DOM添加allowfullscreen
属性,于是就想着用window.parent.frames
得到父页面所有的frame,然后遍历匹配每个frame和自己当前的frame的location进行比较,但总觉得这是个比较多余的操作,总觉得应该有一个api直接就能得到当前iframe在父页面的标签DOM。(遍历的时候遇到的一个问题是,有一个iframe是空白页,结果在firefox下抛异常了,于是还得捕获异常)
而这个属性,就是这么个意思,又要祭出MDN文档,返回嵌入当前window对象的元素,当页面是顶层页面或者父子页面之前存在跨域时,返回null。
这要不是在工作中运用遇到问题,估计很长一段时间保持的原来的无知状态(以前用iframe都没涉及到这块内容)。想想正好月初,把这两点记下来交任务了~