2014-07-08 94 views
2

我不會說英語很好。Javascript - 等待用戶交互而不凍結瀏覽器

我的公司已經開發了一個網絡瀏覽器的Web應用程序,非常劇烈地使用功能showModalDialog並等待結果。

我們正計劃擴大該應用使用其他瀏覽器(火狐,Chrome),我需要將所有的瀏覽器很好地工作邏輯來代替「showModalDialog邏輯」。

我最初嘗試使用ajaxcontroltoolkitmodalpopupiframe裏面。

我的問題是,我已經顯示modalpopup之後,我不能等待用戶關閉彈出窗口而不凍結Web界面。

function OpenDialog() { 
    var result = window.showModalDialog("page1.html", "input_parameter", "width:100px; height:100px"); 

    //When the popup went closed 
    alert("result: " + result); 
} 

//Override showModalDialog function for compatibility with other browser 
function myShowModalDialog(url, pars, options) { 

    //show a jquery modalpopup or ajaxcontroltoolkit modalpopup with an iframe .... 
    iframe.src = url; 

    //I need to wait here until the modal popup closed 
    //HOW? 

    //get the value from popup 
    var res = ???????; 

    return res; 
} 

window.showModalDialog = myShowModalDialog; 

我無法更改webapp中每個頁面的邏輯。

我搜索了一種方法來覆蓋showModalDialog函數並重新創建相同的邏輯(等到彈出窗口關閉並獲得彈出窗口爲調用者提供的結果)。

任何想法?感謝所有

+0

考慮設計一個絕對定位的面板,而不是打開一個窗口或ASO等待iframe中。您可以創建一個全尺寸覆蓋圖,捕捉所有事件並取消它們。 –

+0

從代碼等待的意義上說,您無法創建模態對話框。相反,使用事件並在關閉對話框時觸發事件。從您的代碼中檢索您的結果,而不是等待它。 – hotforfeature

+0

@Quasimodo:是的,我要使用這個組件:http://www.asp.net/AjaxLibrary/AjaxControlToolkitSampleSite/ModalPopup/ModalPopup.aspx – bdn02

回答

2

您已經發現JavaScript嚴重依賴異步性,事件處理函數和回調函數的原因。

最好的解決方案是重構你的代碼,以便你的事件在事件處理器上觸發,使用jQuery或其他方法將事件處理程序綁定到事件上。或者,您可以始終使用timeout loop中的函數定期檢查模式是否已關閉,並在代碼執行時繼續執行代碼。雖然這很黑,我不推薦它。一般來說,試圖強制異步代碼來適應同步模型變得非常混亂。

+0

我同意事件處理程序,但不同意超時循環。如果他加入'OpenDialog超時循環()',仍然會鎖定瀏覽器 – hotforfeature

+0

是的,我想你是對的 – bdn02

0

除非我沒有關注你,否則你需要的是當用戶關閉對話框時的回調,對吧?

無論用戶關閉對話框時執行什麼方法,猴子都會打補丁來調用你的函數。 (猴子補丁是爲現有代碼添加功能的代碼,但也保留舊代碼)。

所以,如果你的親密方法/函數的樣子:

myCloseDialog = function(){ 
    // do important closing stuff 
} 

然後你就可以猴子補丁,像這樣:

myNewCloseDialog = function(){ 
    // do important callback stuff, or call your callback function 
    myCloseDialog(arguments); 
} 

順便說一句,你的英語非常精細:)

0

我在評論中創建了我的建議的簡短演示:

<!DOCTYPE html> 
<html> 
    <head> 
    <title>modal overlay</title> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <style> 
     .overlay 
     { 
     background-color: rgba(0, 0, 0, 0.1); 
     position:absolute; 
     top:0; 
     left:0; 
     width:100%; 
     height:100%; 
     z-index: 100; 
     margin:0; 
     display:none; 
     } 
     .box 
     { 
     position:absolute; 
     top:0; 
     left:0; 
     bottom:0; 
     right:0; 
     width:400px; 
     height:300px; 
     background:white; 
     margin:auto; 
     padding:10px; 
     } 

    </style> 

    <!-- 
     prepare a style to show/hide overlay and 
     prevent lost focus when clicking outside the box 
    --> 
    <template id="template1"> 
     <style id="style-modal"> 
     * 
     { pointer-events: none; 
     } 
     .overlay * 
     {pointer-events: auto; 
     } 
     .overlay 
     { display:block!important; 
     } 
     </style> 
    </template> 
    </head> 
    <body> 
    <input id="some-input1" type="text"> 
    <button class="modal-open" type="button">open modal dialog</button> 

    <div id="overlay1" class="overlay"> 
     <div class="box"> 
     <input id="modal-input1" type="text"> 
     <button type="button" class="modal-close">close</button> 
     </div> 
    </div> 

    <script> 
     document.addEventListener 
     ('DOMContentLoaded', 
     function(ev) 
     { 
      var 
      template1 = document.getElementById('template1'), 
      styleModal = template1.content.getElementById('style-modal'), 
      overlay1 = document.getElementById('overlay1'), 
      box  = overlay1.querySelector('.box'), 
      head  = document.querySelector('head') 
      ; 

      //TODO: could iterate over querySelectorAll 
      document.querySelector('button.modal-open').addEventListener 
      ('click', 
      function(ev) { head.appendChild(styleModal); }, 
      false 
     ) 

      overlay1.querySelector('button.modal-close').addEventListener 
      ('click', 
      function(ev) 
      { template1.content.appendChild(styleModal); 
       document.dispatchEvent(new CustomEvent('closemodal', {detail:{relatedTarget:box}})); 
      }, 
      false 
     ) 
     }, 
     false 
    ); 

     document.addEventListener 
     ('closemodal', 
     function(ev){ alert(ev.detail.relatedTarget.querySelector('input').value); }, 
     false 
    ); 
    </script> 
    </body> 
</html> 

請注意,此示例使用了尚未由IE實現的<template>元素。您可以在腳本中輕鬆生成樣式元素,將其保存在變量中,並將其添加到頭部或從頭部添加/刪除。

+0

謝謝你的樣品,但我的問題是不重疊。我的問題是,我有一個功能(對話框開啓功能,button.modal打開點擊你的例子),可以等待,直到模態已關閉 – bdn02

0

有使用模式元素和ECMAScript 6臺發電機看看我showModalDialog polyfill,所以它並不需要一個明確的回調函數。關閉模式後,showModalDialog()之後的聲明將會運行。