2014-07-08 48 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()之后的声明将会运行。