2017-02-06 100 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:方法中的任何邏輯。如果您希望執行該方法,您必須重新創建該邏輯。