填坑之路:iframe的各种坑

连着两个项目遇到iframe,难受。

同域还好,不同域简直爆炸。

当然几经折磨,还是有了办法。

解决方案就是让它们变同域了,那做法就是在父子两个窗口设置一样的 domain 。 当然这个 domain 也不是随便设置的,至少保证二者有那么点类似,不然

常见改domain问题,意思就是dev.web.nd 不是你的127.0.0.1的后缀,不要瞎搞。

比如现在父窗口域名http://abc.dev.web.com ,子窗口域名http://d.ef.dev.web.com 那现在我们可以发现二者的域名后半部分dev.web.com是一样的,那么我们就可以在两个页面的入口 js 文件内写上 document.domain = 'dev.web.com',那么二者就同域了(本地测试考虑改host文件,或者将二者设为同域如127.0.0.1不同端口).

总之,整体的思路就是取二者相同的域名部分来设domain(dev.web.com 不行就换 web.com,再不行就 com 总有一个能一样吧!)


那现在同域了以后就好办了。

1. 父窗口操作子窗口dom

JS

// 操作dom
document.getElementById("frameId").contentWindow.document.getElementById("ooxx").style.color="#F00"

// 操作方法
window.frames["iframeName"].childFun();

其中contentWindow属性支持所有主流浏览器,contentDocument被IE6,7拒了。

JQ

$('#iframeId').contents().find('ooxx').css('color','#F00')

注意

在实际使用中,我们可能会需要对iframe中的dom节点绑定事件,一直绑不上事件的原因狠狠狠有可能就是你在父窗口的 ready(onload)中压根就没加载到 dom(iframe子窗口内的dom何时加载完成不能确定),所以,一个比较 low 的做法是轮询下 dom 是否加载完全:

let findObj = setInterval (function () {
    if ($("#iframeId").contents().find('ooxx').length > 0) {
        clearInterval(findObj)
        $("#iframeId").contents().on('click', 'ooxx', function() {
            dosomething()
        })
    }
}, 1000)

还有一个要知道的就是可以在 iframe 的 src 中大做文章,很多时候可以把需要的一些信息附在src中,比如src='http://abc.dev.web.com?access_token=abc&mac_key=cfd 之类的,子窗口就可以通过读取url来操作,方便得很。

2. 子窗口操作父窗口

JS

首先搞懂几个对象:

  • parent:父窗口 ;
  • top:顶级父窗口。一种情况是top==parent,这时候两者没差别 ;
  • self:当前窗口,即 window ;
  • opener:open 方法打开窗口的原窗口 ;
// 操作dom
parent.document.getElementById("ooxx").style.color="#F00";

// 操作方法
parent.parentFun("ooxx");

JQ

$(parent).find('ooxx').css('color','#F00')

你可能感兴趣的:(填坑之路:iframe的各种坑)