2013-06-19 3 views
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» остается пустым (он будет установлен обратными вызовами на кнопках, которые добавляются в меню до его открытия). Вспомогательный вопрос заключается в том, почему моя «формулировка выхода» с более длинным таймаутом не срабатывает?

+0

Какую всплывающую библиотеку/виджет вы используете? – hamstu

+0

Обратите внимание, что использование оператора double equals в javaScript '! PopupResult == false == null == undefined == 0 == '' == NaN'. просто используйте не оператор, а для специальных проверок тройка равна, например, это «null! == false». – metadings

+0

Я использую jQuery mobile 1.3.1. Хороший вопрос об операторах ==, но это один простой пример - я буду его менять, чтобы popupresult мог быть 0,1,2 и т. Д., В зависимости от того, какая кнопка была нажата. – quilkin

ответ

0

Можете ли вы использовать интерфейс JQuery? Он поставляется с собственным Modal Dialog.

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

+0

Смотрите мой комментарий на ответ @hamstu выше , диалог jquery Ui также полагается на обратные вызовы для нажатия кнопок, и все они продолжают обработку за пределами точки, в которой вызывается всплывающее окно, - они не ждут ответа, а не по-настоящему модального (в моем смысле слова в любом случае) – quilkin

1

Изменить

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

в

afteropen: wait 

или

afteropen: function() { wait(); } 

В настоящее время вы бесконечны делать wait и никогда не оставит петля. Это также создает неограниченные таймауты.

Используя изменения вы делаете когда «ожидание» - что это повторно SetTimeout до 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); 
+0

Удаление ' while (popupResult == null) 'просто возвращает popup с нулевым результатом; он не ждет, пока пользователь что-нибудь выберет. Хороший момент, хотя и о моей статье «get-out» с тайм-аутом 30000, хотя я только на самом деле поставил это как часть попытки решить исходную проблему. – quilkin

+0

Я не понимаю это прямо сейчас, когда вы устанавливаете «возвращаемое значение диалога» (я не очень хорошо знаком с jQuery mobile;)) однако 'while (popupResult == null)' не устанавливает или не возвращает ничего, кроме циклов, бесконечное, блокирование любого последующего исполнения - javaScript однопоточный - поэтому setTimeout создает тайм-ауты, но это никогда не произойдет, пока вы не уйдете. – metadings

2

Как уже было сказано, вы, вероятно, может найти пре- решение вашей проблемы; Есть тонн 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.) 
}); 

Надеюсь, это имеет смысл.

+0

Да, есть много модальных всплывающих окон, но все они требуют обратных вызовов для каждого выбранного элемента, и все они позволяют обрабатывать продолжение всплывающего окна до того, как пользователь получит ответ. Мы не можем, например, поставить «break» (из цикла) в качестве обратного вызова. Также в моем случае (и часто в общем случае) после всплывающего меню происходит дальнейшая обработка, и эта обработка зависит от результата всплывающего окна. – quilkin

+1

Невозможно приостановить выполнение и ждать, как вы просите; это просто невозможно в JavaScript, у вас ** есть ** для использования обратных вызовов, как я показал. Если у вас есть код, зависящий от результата модальности, то поместите его в другую функцию и вызовите эту функцию, когда пользователь сделал выбор. – hamstu

+1

ОК, спасибо, я согласен, что то, что я пытаюсь, невозможно; Я просто должен привыкнуть к этой однопоточности (сложно после многих лет .NET-кодирования!) И реструктурировать большую часть моего кода. ... – quilkin

Смежные вопросы