提问人:quilkin 提问时间:6/20/2013 更新时间:6/20/2013 访问量:1100
尝试制作模态弹出菜单
Trying to make a modal popup menu
问:
我正在尝试创建一个模式弹出窗口(例如,用于是/否确认),以便在弹出窗口得到响应之前代码不会继续执行。我知道推荐的方法是为每个按钮(菜单项)添加回调,但是当菜单是循环的一部分并且其中一个结果可能是循环的“中断”而不是函数调用时,这种方法会出现问题。 无论如何,我在这里想出了代码,使用 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”仍为 null(它将由在打开菜单之前附加到菜单的按钮上的回调设置)。 一个次要问题是,为什么我的“退出条款”没有触发更长的超时时间?
答:
你能使用 JQuery UI 吗?它带有自己的模态对话框。
http://jqueryui.com/dialog/#modal
评论
改变
afteropen: function () {
while (popupResult == null)
wait();
}
自
afteropen: wait
或
afteropen: function () { wait(); }
目前,您无休止地做,永远不会离开循环。这也会产生无限的超时。wait
使用您正在执行的更改一次“等待” - 这确实会重新设置Timeout,直到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);
评论
while (popupResult == null)
如前所述,您可能会找到解决问题的预制解决方案;那里有大量的jQuery模式弹出窗口和框(Google是你的朋友。也就是说,我至少可以看到一个问题:
$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.)
});
我希望这是有道理的。
评论
!popupResult == false == null == undefined == 0 == '' == NaN
null !== false