2

我正在尝试创建一个模式弹出窗口(例如,用于确认是/否),这样代码在弹出窗口得到回答之前不会继续执行。我知道推荐的方法是为每个按钮(菜单项)添加回调,但是当菜单是循环的一部分并且结果之一可能是循环的“中断”而不是函数时,此方法会出现问题称呼。无论如何,我在这里使用 jquery 1.3 弹出小部件提出了代码:

var $popUp;
var popupResult;
function wait()
{
    if (popupResult == null) {
        setTimeout(wait, 100);
    }
    else
        return;
}

function CreatePopupMenu(title)
{
    popupResult = null;
    // for safety, timeout the popup if it isn't answered
    setTimeout(function(){ popupResult = false;  }, 3000);
    $popUp = $("<div/>").popup({
        dismissible: false,
        theme: "c",
        afteropen: function () {
            while (popupResult == null)
                wait();
        }
    }).on("popupafterclose", function ()
    {
        $(this).remove();
    });
    $("<h4/>", {  text: title }).appendTo($popUp);
}

问题是,弹出窗口实际上并没有出现,代码直接运行到“afteropen”回调中。如果弹出窗口没有出现,则用户不能使用按钮设置“popupResult”,因此等待将永远继续。如果我删除“afteropen”回调,弹出窗口会按预期显示,但现在“popupResult”仍然为空(它将由在打开之前附加到菜单的按钮上的回调设置)。一个附属问题是,为什么我的超时时间较长的“退出条款”不会触发?

4

3 回答 3

2

如前所述,您可能可以找到针对您的问题的预制解决方案;那里有大量的 jQuery 模态弹出窗口和框(谷歌是你的朋友。)也就是说,我至少可以看到一个问题:

$popUp = $("<div/>").popup({
  dismissible: false,
  theme: "c",
  afteropen: function () {
    /* while (popupResult == null) */ // <-- REMOVE THIS LINE
    wait();
  }
})

while循环是不必要的。事实上,在这种情况下,您很少会想使用while循环。您实际上是在启动一个无限循环(因为它会阻止其他代码的执行、浏览器渲染等)。尝试删除它,您的代码应该可以按预期工作。(我没有测试过这个。)


更好的方法是像这样在 HTML 中构建弹出窗口:(您也可以在 jQuery 中创建此代码,类似于您的示例)

<div class='popup' id='myPopup'>
  <h2>Popup Title</h2>
  <a href='#' class='action' data-action='close'>Close</a>
  <a href='#' class='action' data-action='other'>Press Me!</a>
</div>

然后,您只需将事件处理程序(即回调)附加到链接/按钮。

$('.popup a.action').on('click', function(event) {
   var action = $(this).data('action');
   // Do something... (Close popup, etc.)
});

我希望这是有道理的。

于 2013-06-19T23:53:54.640 回答
1

改变

afteropen: function () {
    while (popupResult == null)
        wait();
}

afteropen: wait

或者

afteropen: function () { wait(); }

目前你无休止地做wait并且永远不会离开循环。这也会产生无限超时。

使用您所做的更改“等待”一次 - 确实会重新设置超时,直到 popupResult 不再!


顺便说一句:这条线可能不会,甚至会干扰你的意图。如果这是由浏览器在用户选择答案和下一个“等待”超时之间执行的 - 这将重置用户的更改。

setTimeout(function(){ popupResult = false;  }, 3000);

最好将waitTimeout保存在wait

var waitTimeout;

function wait() {
    if (!popupResult) {
        waitTimeout = setTimeout(wait, 100);
    }
}

因此,您可以执行clearTimeout并自动关闭弹出窗口:

setTimeout(function () {
    if (waitTimeout) {
        clearTimeout(waitTimeout);
        waitTimeout = undefined;
    }
    popupResult = undefined;
    $popUp.close();
}, 3000);
于 2013-06-19T23:48:34.340 回答
0

可以使用 JQuery UI 吗?它带有自己的模态对话框。

http://jqueryui.com/dialog/#modal

于 2013-06-19T23:34:55.167 回答