博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
artDialog组件与iframe
阅读量:4678 次
发布时间:2019-06-09

本文共 2902 字,大约阅读时间需要 9 分钟。

背景

  。 未用过的朋友可以先了解下。

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

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

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

问题现象

  先看top.html代码。

        

  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的朋友告知一下,谢谢!

 

  

转载于:https://www.cnblogs.com/codealone/p/3540086.html

你可能感兴趣的文章
P3698 [CQOI2017]小Q的棋盘
查看>>
动态规划入门 洛谷P2409 Y的积木
查看>>
【第一季】CH04_FPGA设计Verilog基础(一)Enter a post title
查看>>
telnet不能用!!!提示:-bash: telnet: command not found
查看>>
隐式转换的一点想法
查看>>
web框架前言与学生数据库系统(附1.0源码)
查看>>
JavaScript基础
查看>>
Linux多线程服务端编程:使用muduo C++网络库
查看>>
log4j配置文件中的additivity属性
查看>>
马后炮之12306抢票工具(二) -- 联系人&获取车次
查看>>
Android系统之Broadcom GPS 移植
查看>>
[bzoj1901]: Zju2112 Dynamic Rankings
查看>>
[bzoj4240] 有趣的家庭菜园
查看>>
递归算法
查看>>
bzoj 3357: [Usaco2004]等差数列
查看>>
Server Tomcat v7.0 Server at localhost failed to start.
查看>>
js数据结构之列表的详细实现方法
查看>>
【转】eclipse 安装插件
查看>>
js基础学习之-js全局对象
查看>>
解决【win10管理员已阻止程序运行】问题时有感
查看>>