尝试制作模态弹出菜单

时间:2013-06-19 23:31:12

标签: javascript jquery

我正在尝试创建一个模态弹出窗口(例如,对于是/否确认),这样在响应弹出窗口之前代码不会继续执行。我知道推荐的方法是为每个按钮(菜单项)添加回调,但是当菜单是循环的一部分并且其中一个结果可能是循环中的“中断”而不是函数时,此方法会出现问题呼叫。 无论如何,我在这里使用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'保持为空(它将由按钮上的回调设置,这些按钮在打开之前附加到菜单上)。 一个附属问题是,为什么我的'get-out clause'没有更长的超时时间?

3 个答案:

答案 0 :(得分: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.)
});

我希望这是有道理的。

答案 1 :(得分:1)

更改

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

afteropen: wait

afteropen: function () { wait(); }

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

使用您正在做的更改'等待' - 这会重新设置TimeTime,直到popupResult不再是!


顺便说一下:这条线可能无法做甚至干扰你的意图。如果浏览器在用户选择答案和下一次“等待”超时之间执行此操作,则会重置用户的更改。

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

最好在wait

中保存waitTimeout
var waitTimeout;

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

所以你可以clearTimeout并自动关闭弹出窗口:

setTimeout(function () {
    if (waitTimeout) {
        clearTimeout(waitTimeout);
        waitTimeout = undefined;
    }
    popupResult = undefined;
    $popUp.close();
}, 3000);

答案 2 :(得分:0)

您可以使用JQuery UI吗?它随附了自己的Modal Dialog。

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