iframe跨域问题思考

来源:互联网 发布:多玩数据库5.4 编辑:程序博客网 时间:2024/05/29 05:07

工作遇到一个bug,弹窗调整至顶层window.top.dialog,使用的artDialog弹窗插件,本来用的好好的,可是随着需求的增加,bug就出现。

需求:在一个弹窗基础上,再添加弹窗展示某项数据,后台接口请求数据

代码现状:那个弹窗是通过iframe引用一个新的页面展示,我要在那个iframe引用的页面添加另外弹窗


问题:1.那个弹窗若是保证正常展示,那个弹窗展示也是在iframe框架内部,很小,跟要求的全屏遮罩展示有差距

    2.抛开上面美观,降低需求标准貌似也行得通,毕竟功能达标,但是另外一个新需求彻底打破:三层弹窗,就是在第二层弹窗基础上再次开第三个弹窗

    3.既然绕不开,那就使用顶层弹窗window.top,问题随之而来,iframe内部的dom元素找不到,html控件操作失效,只剩下事件

   4.引用的那个页面是新页面,但在同个主域名下

问题原因:js的操作dom元素的api都是基于document文档,iframe内部也遵循这个原理。现在认为置顶弹窗,突破iframe限制,导致正常api找不到dom元素

问题解决:1.改变查询范围,也就是作用域。js和那些插件,例如jQuery等默认都是document范围查找。

同域下:使用 window.top或者window.parent.parent获取浏览器最顶层window对象的引用。可以使用:window.parent.parent.document最顶层元素的DOM对象window.parent.parent.document.getElementsByTagName("html")来获取父页面的HTML元素。

jQuery写法:
$('xxx',window.parent.document)

主要问题解决了,不过项目中的弹窗需要用到一些事件,radio单选框,input文本输入框。由于跨域,为单选框加上class类不起作用,input文本框的value值也获取不到。可能是我以前没遇到过此类问题,没有经验。我的办法是,重新绑定事件,重新为radio绑定onclick事件(重新插入class类样式),为input文本框绑定onchange(直接返回value)


jquery写法:单选框:重新书写点击事件的样式<span><input type="radio" name="radio1"/></span><span><input type="radio" name="radio1"/></span><span><input type="radio" name="radio1"/></span>$(window.parent.document).on('click','input[type="radio"]',function(){$(this).parent().addClass('checked');$(this).parent().siblings().removeClass('checked');})文本框:value值获取不到,所以需要change事件获取<input type="text" placeholder="请输入xxx" />$(window.parent.document).on('change','input[type="text"]',function(){var value = this.value;})

事情到了这里,我门还必须注意问题,iframe加载是否完毕,所以我们还需要监听iframe加载事件。

要确保在iframe加载完成后再进行操作,如果iframe还未加载完成就开始调用里面的方法或变量,会产生错误。判断iframe是否加载完成有两种方法: 

1. iframe上用onload事件 

2. 用document.readyState=="complete"来判断 

由于用到弹窗(artDialog插件),当我们使用window.top.dialog时候,如果有多重弹窗,那么有可能会造成冲突,导致确定按钮无法关闭。公司项目就无法自动关闭,我在这里使用了手动关闭。

//手动关闭dialog//自定义dialog的idvar dialog1 = art.dialog({    title: '欢迎',    content: '欢迎使用artDialog对话框组件!',    icon: 'succeed',    follow: document.getElementById('btn2'),    ok: function(){        window.top.dialog1.close();//确定按钮无法自动关闭弹窗时候,这个方法就能够解决问题        return false;    }});

以上算是对项目bug的一点笔记,关于iframe跨域种种,具体的可以看下面参考链接,讲的挺不错。



参考网址: http://www.jb51.net/article/49809.htm

http://www.cnblogs.com/duankaige/archive/2012/09/20/2695012.html

http://blog.csdn.net/j_y_x_8/article/details/50907366

原创粉丝点击