背景

  组件官网。 未用过的朋友可以先了解下。

  当Content参数传递html元素时,官方的解释是:

备注:1、元素不是复制而是完整移动到对话框中,所以原有的事件与属性都将会保留 2、如果隐藏元素被传入到对话框,会设置display:block属性显示该元素 3、对话框关闭的时候元素将恢复到原来在页面的位置,style display属性也将恢复

  如果说该元素是页面本身,最终显示的载体也是页面本身,那么没有任何问题。但在使用了iframe下会有个奇怪的问题,当元素为iframe时,在chrome下,frame会重新加载一次。

问题现象

  先看top.html代码。

    <iframe id="ff" src="child1.html"></iframe>
<input type="button" onclick="fn()" value="弹出黄色Frame(在Chrome下frame会重新加载一次,所以值丢失了)" />
<script>
function fn() {
$.dialog({
title: '测试',
content: document.getElementById("ff")
});
}
</script>

  child1页面上有个输入框,每次加载时会显示重新加载。我们可以在里面输入,会发现点击button后,IE(本机IE8)下正常,输入的值未丢失。在Chrome下frame会被重新加载一次,导致输入的值丢失了。

  这样带来的问题是:init事件则有问题。init是在对话框弹出后会执行的函数,我们希望在弹出一个frame后,加载frame的数据等,而此时init函数就不能发挥作用。既然是iframe重新加载了,导致了这个问题,那么init的执行时机应该是当frame加载完毕后,再调用init事件。通过一翻搜索,找到兼容各种浏览器监听iframe加载完毕的代码:

 thisFrame.onload = thisFrame.onreadystatechange = function () {
if (this.readyState && this.readyState != 'complete') return;
thisFrame.onload = _top.frames[config.content.name].onreadystatechange = null;
//执行方法
};

  于是我修改init的事件则为: 

if(webkit){ //若是chrome
thisFrame.onload = thisFrame.onreadystatechange = function () {
if (this.readyState && this.readyState != 'complete') return;
thisFrame.onload = _top.frames[config.content.name].onreadystatechange = null;
//执行方法
};
}
else{
//执行方法
}

  到这里问题算是基本上解决了。

进一步处理

  首先解释下为什么要使用frame。

  对话框需要穿越。例如主页top.html,有个frame专门用来显示具体的内容。某个内容页需要弹出数据的详情对话框,而且该对话框里面在top顶部,所以使用了artDialog提供的穿越机制,它可以直接将元素显示top页面的最上方。但由于artDialog的做法是将元素完整移动,所以如果是普通的div,该div又引用了很多js,穿越后会出问题,相应的事件会提示缺少js。

  当然如果把这个div需要的js或css一律拷贝到top页面上,是没有问题的,但这样肯定不好。所以我使用了iframe,相关的js和css都在frame内部,故不存在穿越后缺少js或者css问题。

  这也引出了我自己的需求,希望在显示穿越对话框并且元素为frame时,init事件能被顺利加载

  上面的初步解决,虽然达到了目的,但是如果每个调用的地方都这么写,会不会有点郁闷。所以我改写了iframeTools.js文件下的through方法,做了这样一个判断,请看:

    artDialog.through = _proxyDialog = function () {
var config = arguments[0];
//检测元素是否是frame,如果是,init的执行时机则必须保证在iframe加载完毕后,在chrome模式下,弹出frame元素会导致frame重新加载
if (config.init && config.content.tagName && config.content.tagName == 'IFRAME' && webkit) {
var tmpfn = config.init;
arguments[0].init = function () {
var thisFrame = _top.frames[config.content.name];
thisFrame.onload = thisFrame.onreadystatechange = function () {
if (this.readyState && this.readyState != 'complete') return;
thisFrame.onload = _top.frames[config.content.name].onreadystatechange = null;
tmpfn();
};
}
}
var api = _topDialog.apply(this, arguments);
// 缓存从当前 window(可能为iframe)调出所有跨框架对话框,
// 以便让当前 window 卸载前去关闭这些对话框。
// 因为iframe注销后也会从内存中删除其创建的对象,这样可以防止回调函数报错
if (_top !== window) artDialog.list[api.config.id] = api;
return api;
};

  代码增加了一个判断,如果through时定义了init,content是frame,并在webkit核心浏览器下,将init方法套一层监听frame加载。

  最后一点疑惑,为什么artDialog弹出frame元素时,在chrome下会重新加载一次。希望使用artDialog的朋友告知一下,谢谢!

测试代码

  

artDialog组件与iframe的更多相关文章

  1. artDialog组件应用学习(一)

    个人觉得artDialog是一组很不错的对话框组件.写的是artDialog_v6应用. 官方称其兼容性测试通过:IE6~IE11.Chrome.Firefox.Safari.Opera. 官网:ht ...

  2. artDialog组件应用学习(五)

    一.artDialog事件应用 对话框编写代码 function DialogEvent() { seajs.use(['jquery', '/Scripts/arale/artDialog/src/ ...

  3. artDialog组件应用学习(四)

    一.在对话框自定义操作按钮 预览: html调用代码: var btnArray = [ { value: '同意', callback: function () { this.content('你同 ...

  4. artDialog组件应用学习(三)

    一.可以加载url的对话框 预览: 对话框编写代码 //弹出一个对话框,加载页面 function OpenBox(url, title, width, height) { seajs.use(['j ...

  5. artDialog组件应用学习(二)

    一.没有操作选项的对话框 预览: html前台引入代码:(之后各种效果对话框引入代码致,调用方法也一样,就不一一写入) <script type="text/javascript&qu ...

  6. angular6 iframe应用

    问题一. iframe如何自适应屏幕高度 解决思路:通过设置iframe外层父元素高度等于window高度,再相对于父元素定位iframe元素:案例如下: 第一步: 模板文件中使用iframe // ...

  7. layui navTree 动态渲染菜单组件介绍

    navTree.js 简介 extends/navTree.js 是一个基于 layui 扩展的模块化组件,用于构建后台布局系统中的垂直导航菜单与水平导航菜单. extends/navTree.js ...

  8. vue文件流转换成pdf预览(pdf.js+iframe)

    参考文档:https://www.jianshu.com/p/242525315bf6 PDFJS: https://mozilla.github.io/pdf.js/     支持获取文件流到客户端 ...

  9. 分享一个自己写的MVC+EF “增删改查” 无刷新分页程序

    分享一个自己写的MVC+EF “增删改查” 无刷新分页程序 一.项目之前得添加几个组件artDialog.MVCPager.kindeditor-4.0.先上几个效果图.      1.首先建立一个数 ...

随机推荐

  1. 改进的平台设备驱动——dev和drv完全分离

    这是平台设备: 1 #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> # ...

  2. C++ 无符号整型和整型的区别

    在Win 7系统中,short 表示的范围为 - 32767到 32767,而无符号的short表示的范围为0 到 65535,其他类型的同理可推导出来,当然,仅当数字不为负的时候才使用无符号类型. ...

  3. poj 3087 直接模拟

    题意:意思就是,s1,和s2两堆牌,然后先s2一张再s1,最后会出现一个s12序列,例如s1 AHAH S2 HAHA 然后s12为HAAHHAAH,然后前面一部分给s1,后面一部分给s2,然后再重复 ...

  4. [Bzoj2282]消防(二分答案+树的直径)

    Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家 ...

  5. scrapy进行分布式爬虫

    今天,参照崔庆才老师的爬虫实战课程,实践了一下分布式爬虫,并没有之前想象的那么神秘,其实非常的简单,相信你看过这篇文章后,不出一小时,便可以动手完成一个分布式爬虫! 1.分布式爬虫原理 首先我们来看一 ...

  6. HTML介绍和head标签-01

    主要内容 web标准 浏览器介绍 开发工具介绍 HTML介绍 HTML颜色介绍 HTML规范 HTML结构详解 一.web标准 web准备介绍: w3c:万维网联盟组织,用来制定web标准的机构(组织 ...

  7. CSS计数器(自定义列表)

    概念 CSS3计数器(CSS Counters)可以允许我们使用css对页面中的任意元素进行计数,实现类似于有序列表的功能(自定义有序列表) 与有序列表相比,它的突出特性在于可以对任意元素计数,同时实 ...

  8. 容器技术Docker

    什么是decker容器 简单理解就是将代码和部署环境一起打包的一个容器

  9. PyCharm 解决有些库(函数)没有代码提示

    问题描述: 如图,当输入 im. 没有智能提示第三库相应的函数或其他提示. 解决方案: python是动态强类型语言,IDE无法判断Image.open("panda.png")的 ...

  10. ul中li元素横向排列且不换行

    ul { white-space: nowrap; } li { display: inline-block; }     white-space 属性设置如何处理元素内的空白. normal 默认. ...