【问题标题】:Jquery UI: closing nested iframe modal dialogsJquery UI:关闭嵌套的 iframe 模式对话框
【发布时间】:2017-02-06 22:16:57
【问题描述】:

我的 UI 结构有问题,我想知道是否在其中添加一些眼睛可以帮助我看到我缺少的东西,或者如果失败了,可以帮助我找到解决方法。

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

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

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

这里有一些额外的注释可能会有所帮助:由于每个对话框的 appendTo 属性,每个模态 div,无论嵌套级别如何,都被附加到主要的顶级主体元素。通过对话框功能添加按钮(例如示例中显示的“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”按钮会因错误而失败。

【问题讨论】:

    标签: jquery iframe dialog nested


    【解决方案1】:

    这不是答案,而是一种解决方法。简单地说,只需删除使用对话框创建的所有杂物。 我必须强调,这在很大程度上是不得已而为之,即便如此,它也不适合所有人。这取决于几个实现细节,这些细节在浏览器和 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 , 这将存在。否则,它将不存在)。对于任意数量的嵌套对话框,您可以通过查找比对话框的 z-index 小 1 的 z-index 来找到合适的叠加层。然后,它会删除覆盖层和对话框。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-22
      • 2023-04-09
      • 2012-02-16
      • 2016-05-12
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多