Javascript - 等待用户交互而不冻结浏览器

时间:2014-07-08 15:17:38

标签: javascript jquery

我不会说英语。

我的公司开发了一个用于Internet Explorer的Web应用程序,它非常努力地使用函数showModalDialog并等待结果。

我们计划将应用程序的使用范围扩展到其他浏览器(Firefox,Chrome),我需要将“showModalDialog逻辑”替换为适用于所有浏览器的逻辑。

我最初尝试使用内置ajaxcontroltoolkit的{​​{1}} modalpopup

我的问题是,在我显示iframe之后,我不能等到用户关闭弹出窗口而不冻结网络界面。

modalpopup

我无法更改webapp中每个页面的逻辑。

我搜索了一个方法来覆盖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; 函数并重新创建相同的逻辑(等到弹出窗口关闭并获得弹出窗口为调用者提供的结果)。

有什么想法吗?感谢所有

4 个答案:

答案 0 :(得分:2)

您已经发现了JavaScript在很大程度上依赖异步性,事件处理程序和回调函数的原因。

最好的解决方案是重构您的代码,以便您的事件在事件处理程序上触发,使用jQuery或某些事件将事件处理程序绑定到事件。或者,您可以始终使用timeout loop中的函数来定期检查模态是否已关闭,并在代码执行时继续执行。虽然这很hacky,我不推荐它。通常,尝试强制异步代码以适应同步模型会变得非常混乱。

答案 1 :(得分:0)

除非我没有关注你,否则你需要的是当用户关闭对话框时的回调,对吗?

无论用户关闭对话框时执行什么方法,都会对其进行修补以调用您的函数。 (猴子补丁是为现有代码添加功能的代码,但也保留旧代码。)

所以如果你的close方法/函数如下:

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

然后你可以像这样修补补丁:

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

顺便说一句,你的英语非常好:)。

答案 2 :(得分: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>元素。您可以轻松地在脚本中生成样式元素,将其保存在变量中并将其添加到头部或从头部添加。

答案 3 :(得分:0)

使用模态元素和ECMAScript 6生成器查看我的showModalDialog polyfill,因此它不需要显式回调函数。关闭模态后,showModalDialog()之后的语句将会运行。