zoukankan      html  css  js  c++  java
  • EasyUI Tabs + Yii2.0实现iframe方式打开页面(解决共用静态文件引入加载的问题)

      在项目实际开发中,有将打开的各个链接页面隔离的需求(防止静态资源起冲突),这个时候常规思路就是使用iframe来实现!但遇到一个比较棘手的问题,当用easyui Tabs打开一个iframe页面时,怎么解决原有共用静态资源引入的问题。有人建议可以考虑将共用静态资源文件放到一个php文件中,然后每次渲染页面时加载即可,这个时候很多朋友会想到PHP的include()方式,但是每个iframe页面都要include一次,岂不是很麻烦。而且项目的要求是iframe打开和easyui tabs href打开方式要能够自由切换,这就难倒众多小伙伴了!现将实际项目解决该问题的思路和步骤整理如下:

    1、在Yii2.0 layouts下新建iframe.php共用视图文件,代码如下:

     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <?php
    use yiihelpersHtml;
    use yiiootstrapNav;
    use yiiootstrapNavBar;
    use yiiwidgetsBreadcrumbs;
    use yiihelpersUrl;
    use frontendassetsAppAsset; use frontendwidgetsAlert; /* @var $this yiiwebView */ /* @var $content string */ //AppAsset::register($this); $js['jquery.min.js'] = 'js/jquery.min.js'; $js['easyui.min.js'] = 'easyui1.4.1/jquery.easyui.min.js'; $js['easyui.ext.js'] = 'easyui1.4.1/jquery.easyui.ext.js'; $js['easyui-lang.js'] = 'easyui1.4.1/locale/easyui-lang-zh_CN.js'; $js['global.js'] = 'js/global.js'; foreach ($js as $f){ if (is_file($root.'/web/'.$f)) { $t = date('ymdHi', filemtime($root.'/web/'.$f)); echo " <script type="text/javascript" src="{$f}?_t=$t" ></script>"; } } ?> <html lang="<?= Yii::$app->language ?>"> <head> <meta charset="<?= Yii::$app->charset ?>"/> <meta http-equiv="X-UA-Compatible" content="IE=8" /> <link rel="stylesheet" type="text/css" href="easyui1.4.1/themes/insdep/easyui.css" /> <link rel="stylesheet" type="text/css" href="easyui1.4.1/themes/insdep/easyui_animation.css" /> <link rel="stylesheet" type="text/css" href="css/icon.css" /> <link rel="stylesheet" type="text/css" href="css/css.css" /> <script type="text/javascript" src="easyui1.4.1/jquery.edatagrid.js"></script> <script type="text/javascript" src="easyui1.4.1/jquery.easyui.extend.validate.js"></script> <?= Html::csrfMetaTags() ?> </head> <style> * {margin:0px; padding:0px;} html, body {margin:0px; padding:0px; 100%; height:100%} .test_page_loading{position:absolute; z-index:1000; top:0px; left:0px; margin:0px auto; padding:0px; 100%; height:100%; filter:alpha(opacity=80); opacity:1.0; background:#F8F8F8; text-align:center} </style> <body> <!--首页遮罩--> <div class="test_page_loading"><div style="margin:20% auto"><image src="css/icons/loading.gif"/><font color="#15428B">页面正在加载中,请稍后···</font></div></div> <?=$content?> </body> </html>

    2、因为要兼顾easyui href打开方式与iframe打开方式并存,而又不能影响原来的业务流程,故在视图文件main.php中打开的href加上一个是否是iframe的识别标记,如下所示:

         // 添加tabs
            addTab: function(node) {
                href = node.href;
                if (href=='' || href==undefined) {
                    return;
                }
                if (node.reload == undefined){
                    reload = 0;
                }else{
                    reload = parseInt(node.reload);
                }
    
                // 根据text查tab是否存在,如果存在则判断id是否一致,一致则直接选中,不一致则新建一个tab
                mark = node.mark;
                text = node.text;
                href = node.href;
                icon = node.icon != 'null' ? node.icon : '';
                outer= parseInt(node.outer);
                
                var loadingHtml = '<div class="test_page_loading"><image src="css/icons/loading.gif"/><font color="#15428B">页面正在加载中,请稍后···</font></div>';
                var tabsPanel = $('#test-main-tabs');
                var tabsLength = tabsPanel.tabs('tabs').length; // 获取选项卡的长度(数量)
                var tabsMaxLength = 10; // 定义选项卡的最大长度
                var tab = $('#test-main-tabs').tabs('getTab', text );
                var tabId =  'user_menu_'+mark;
                if (tab && $(tab).attr('id') == tabId){
                    tabsPanel.tabs('select', text);
                    if (reload){
                        if (outer){
                            var tab = tabsPanel.tabs('getSelected');
                            /*if (tab){
                                var index = tabsPanel.tabs('getTabIndex', tab);
                                tabsPanel.tabs('close', index);
                            }*/
                            // 包含?的url链接加上额外参数,解决打开外部链接404问题
                            if (/?/g.test(href)) {
                                href = href + "&isFrame=true"; // 加上iframe打开方式标记
                            }
                            var content = '<iframe scrolling="auto" frameborder="0"  src="'+ href +'" style="100%;height:100%;"></iframe>';
                            if(tabsLength > tabsMaxLength){
                                $.messager.alert('提示信息', '为了您的浏览器性能,您最多允许打开'+tabsMaxLength+'个tabs窗口,请先关闭无用的窗口!', 'error');
                                return false;
                            }
                            tabsPanel.tabs('update',{
                                tab: tab,
                                options: {
                                    id: tabId,
                                    title: text,
                                    iconCls: icon,
                                    content: content,
                                    fit:true,
                                    closable:true                                
                                }
                            });
                        }else{
                            // 注意,tab中如果有dialog之类的,多次刷新tab会导致内存中有多个同样的dialog
                            tabsPanel.tabs('getSelected').panel('refresh', href);
                        }
                    }else{
    
                    }
                }else{
                    if (outer){
                        // 包含?的url链接加上额外参数,解决打开外部链接404问题
                        if (/?/g.test(href)) {
                            href = href + "&isFrame=true";
                        }                    
                        var content = '<iframe scrolling="auto" frameborder="0"  src="'+ href +'" style="100%;height:100%;"></iframe>';
                        if(tabsLength > tabsMaxLength){
                            $.messager.alert('提示信息', '为了您的浏览器性能,您最多允许打开'+tabsMaxLength+'个tabs窗口,请先关闭无用的窗口!', 'error');
                            return false;
                        }
                        tabsPanel.tabs('add',{
                            id: tabId,
                            title: text,
                            iconCls: icon,
                            content: content,
                            fit:true,
                            closable:true
                        });
                    }else{
                        if(tabsLength > tabsMaxLength){
                            $.messager.alert('提示信息', '为了您的浏览器性能,您最多允许打开'+tabsMaxLength+'个tabs窗口,请先关闭无用的窗口!', 'error');
                            return false;
                        }
                        tabsPanel.tabs('add',{
                            id: tabId,
                            title: text,
                            iconCls: icon,
                            href: href,
                            closable:true,
                            onBeforeLoad: function() {
                                $('#test-main-tabs').find('.tabs-panels').append(loadingHtml);
                            }
                        });
                    }
                }            
            }

    3、因为根据之前的业务tabs都是通过href直接打开的,现要支持iframe打开而不能影响之前的打开方式,也就是两种方式能够随时切换,那么后台渲染视图也要做相应的调整,如下所示:

        // BaseController.php
        /**
         * 控制器动作执行前事件处理,解决iframe方式打开使用iframe公共视图
         * @author testMe
         * @date 2016-12-04
         */
        public function beforeAction($action)
        {
            // 用iframe方式打开则改变默认的视图布局文件
            $isFrame = Yii::$app->request->get('isFrame', '');
            if ($isFrame == 'true') {
                $this->layout = '@app/views/layouts/iframe';
                self::$_isFrame = true;
            } else {
                self::$_isFrame = false;
            }
            
            return parent::beforeAction($action);
        }
        
        /**
         * 实现页面iframe方式打开时强制渲染公共视图(因为之前的逻辑都是通过renderPartial局部方式渲染的,而通过iframe要启用新的共用视图文件,所以这里强制使用render包含共用视图的渲染方式)
         * @author testMe
         * @date 2016-12-04
         */
        public function renderPartial($view, $params = []) 
        {
            if (self::$_isFrame) {
                return parent::render($view, $params);
            } else {
                return parent::renderPartial($view, $params);
            }
        }
  • 相关阅读:
    CentOS7.4 + Ambari 2.6.1.5 + HDP 2.6.4.0 安装部署
    分布式业务的异常解决思路
    RPC簡介
    网络I/O模型--07Netty基础
    网络I/O模型--06异步I/O
    网络I/O模型--05多路复用I/O
    网络I/O模型--04非阻塞模式(解除accept()、 read()方法阻塞)的基础上加入多线程技术
    网络I/O模型--03非阻塞模式(ServerSocket与Socket的超时处理)--解除accept()、 read()方法阻塞
    网络I/O模型--02阻塞模式(多线程)
    Android开发(五)——计时器
  • 原文地址:https://www.cnblogs.com/itsharehome/p/8003853.html
Copyright © 2011-2022 走看看