2017-02-06 56 views
0

我有一个UI结构是行为不当,我想知道如果增加一些眼睛,它会帮助我看到我失踪的东西,或者,失败,帮助我找到解决方法。jquery用户界面:关闭嵌套的iframe模态对话框

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

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

注意,这是概念上的,DOM是不实际如何布局。另外,page2中实际上有一个关闭iframe1的按钮,它可以工作。但是,尝试第3页和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> 

...和第3页,问题页:

<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> 

的最后,“杀死2”按钮是失败并出现错误。

回答

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(); 
    } 
} 

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

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