Jquery UI:关闭嵌套的iframe模式对话框

时间:2017-02-06 22:16:58

标签: jquery iframe dialog nested

我有一个行为不端的UI结构,我想知道是否添加一些眼睛会帮助我看到我失踪的东西,或者,如果失败了,请帮我找一个解决方法。

我有一个页面加载了一个包含iframe的jquery UI模式对话框。该iframe加载的页面可以打开包含另一个iframe的另一个模态。嵌套的iframe包含一个页面,其中的按钮应关闭当前模式。但是,该按钮不起作用。这是布局的概念模型(注意每个iframe都包含在模态div中):

 - page1
   - iframe1
     - page2
       - iframe2
         - page3
           - button -> close iframe2 (fails)

请注意,这是概念性的,而不是DOM的实际布局方式。此外,第2页实际上有一个关闭iframe1的按钮,它可以工作。但是,尝试page3和iframe2之间的相同功能失败。它能够找到对话框div,但是它给了我“在初始化之前无法在对话框上调用方法;试图调用方法'关闭'”jquery UI错误。

以下是一些可能有用的补充说明:由于每个对话框的appendTo属性,每个模态div(无论嵌套级别)都会附加到主顶级body元素。通过对话框功能添加按钮(例如示例中显示的“X”按钮)有效。很明显,有一个隐藏的钩子可以正常工作。对于SO的每个其他答案,每个iframe已经调用jQuery的父实例来尝试关闭其包含的对话框。添加任意数量的.parent来解释增加的嵌套级别并没有解决问题。

以下是我的示例应用的全文: 第1页

<html>
<head>
<link rel="stylesheet" href="jquery-ui.min.css" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.min.js"></script>
<script type="text/javascript">
    function make1() {
        var self = $("<div id='one'></div>");
        var frame = $("<iframe style='width:100%;height:100%' />");
        self.html(frame);
        self.dialog({
            title: 'One',
            autoOpen: false,
            modal: true,
            appendTo: $(window.document).find('body'),
            width: 300,
            height: 200,
            overlay: 0.5,
            close: function() {
                self.dialog('destroy');
            }
        });
        self.dialog('open');
        frame.attr("src", "http://localhost:81/page2.html");
    }

</script>
</head>
<body>
<button onclick="make1()">Open 1</button>
</body>
</html>

第2页:

<html>
<head>
<link rel="stylesheet" href="jquery-ui.min.css" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.min.js"></script>
<script type="text/javascript">

    var dialog;

    function make2() {
        var self = $("<div id='two'></div>");
        dialog = self;
        var frame = $("<iframe style='width:100%;height:100%' />");
        self.html(frame);
        self.dialog({
            title: 'Two',
            autoOpen: false,
            modal: true,
            appendTo: $(window.parent.document).find('body'),
            width: 300,
            height: 200,
            overlay: 0.5,
            close: function() {
                self.dialog('destroy');
            }
        });
        self.dialog('open');
        frame.attr("src", "http://localhost:81/page3.html");
    }

    function kill1() {
        window.parent.$("#one").dialog('close');
    }


</script>
</head>
<body>
<button onclick="make2()">Open 2</button>
<button onclick="kill1()">Kill 1</button>
</body>
</html>

...和page3,问题页面:

<html>
<head>
<link rel="stylesheet" href="jquery-ui.min.css" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery-ui.min.js"></script>
<script type="text/javascript">

    function kill2() {
        var dialog = window.parent.$("#two")
        if(dialog.length > 0) {
            alert("found it; closing dialog...");
            dialog.dialog('close');
        }
    }


</script>
</head>
<body>
<button onclick="kill2()">Kill 2</button>
</body>
</html>

最后,“Kill 2”按钮失败并出现错误。

1 个答案:

答案 0 :(得分:0)

这不是答案,而是一种解决方法。简而言之,只需删除使用对话框创建的所有内容。 我必须强调,这是最后的手段,即便如此,也不适合所有人。它取决于浏览器和JQuery UI版本之间不同的几个实现细节。但是,如果您处于客户的情况下,浏览器是版本锁定的,这至少应该值得调查。

function kill2() {
    var dialog = window.parent.$("[aria-describedby='two']")
    if(dialog.length > 0) {     
        var zIndex = dialog.css("z-index") -1;
        var overlay;
        dialog.siblings(".ui-widget-overlay.ui-front").each(function(index, item) {
            if($(item).css("z-index") == zIndex)
                overlay = item;
        });
        if(overlay) {
            $(overlay).remove();
        }
        dialog.remove();
    }
}

本质上,它定位对话框的父元素(再次,通过它的实现细节添加aria-desribedby属性),然后它搜索该元素的兄弟为覆盖(如果提供了modal:true) ,这将在那里。否则,它将不存在)。对于任意数量的嵌套对话框,您可以通过查找比对话框小1的z-index找到适当的叠加层。然后,它删除叠加层和对话框。

一个关键的注意事项是,这显然会绕过提供给对话框的close:方法中的任何逻辑。如果您希望它执行,您必须在此方法中重新创建该逻辑。