Синхронизация событий Javascript - PullRequest
0 голосов
/ 24 мая 2009

Есть ли возможность синхронизировать события в javascript?

Моя ситуация следующая: у меня есть форма ввода со многими полями, в каждом из которых зарегистрировано событие onchange. там также есть кнопка, чтобы открыть всплывающее окно для некоторых других / специальных вещей, которые можно там сделать.

Мое требование заключается в том, чтобы события onchange были завершены до того, как я смогу открыть всплывающее окно.

Есть идеи, как этого добиться без использования setTimeout?

РЕДАКТИРОВАТЬ: дальнейшее объяснение требований:

Чтобы прояснить ситуацию, я пытаюсь подробно описать, что я делаю.

Я получил форму с некоторыми элементами ввода (матричная форма ввода заказа, например, статья, серийный номер, количество). Каждый раз, когда пользователь изменяет данные в одном из полей, ajax-вызов инициируется событием onchange для проверки ввода пользователя и считывания дополнительных данных (например, предварительной установки / форматирования одного из других полей). Эти ajax-вызовы тяжелы и требуют много времени, поэтому я должен избегать дублирования проверок. Также есть кнопка, которая открывает всплывающее окно, которое дает пользователю другую форму для изменения данных, которые он вводил перед построчно, поэтому абсолютно необходимо, чтобы все проверки были выполнены до открытия этого всплывающего окна. В данный момент я пытаюсь синхронизировать события onchange и открытие всплывающего окна с помощью setTimeout (всплывающее окно не открывается до того, как все проверки выполнены), что вызывает проблемы на моем сайте клиентов, поскольку эти всплывающие окна блокируются блокировщиком всплывающих окон. Поэтому мне нужно открывать всплывающие окна, не останавливая их каким-либо блокировщиком всплывающих окон (IE 6/7/8).

Из-за моей матричной формы я просто не могу проверить все элементы ввода перед открытием всплывающего окна, мне нужно проверить только те, которые были изменены и еще не проверены (должно быть не более 1).

Ответы [ 7 ]

2 голосов
/ 24 мая 2009

Похоже, вы делаете проверку формы, с автоматическим всплывающим окном, когда форма полностью заполнена Чтобы сделать это, вы пишете одну функцию проверки в javascript, которая проверяет каждое поле в форме. Вы можете запустить эту функцию из каждого из ваших событий OnChange и заставить функцию открывать всплывающее окно, когда вся форма успешно проверяется.

Подумайте о проверке jQuery, когда у вас будет немного свободного времени.

http://jquery.com/

1 голос
/ 24 мая 2009

вы можете настроить небольшой обратный вызов для ваших событий onchange, чтобы убедиться, что вся ваша проверка происходит до появления всплывающего окна.

function onChange(callback)
{
    // Do validation

    // Call the callback
    callback();
}

function showPopup()
{
    // Show the popup
}

Тогда на ваш звонок он-лайн просто позвоните

onChange(showPopup);
0 голосов
/ 19 июля 2009

Нам понадобилось нечто подобное для мастера, где некоторые шаги требовали проверки AJAX. Пользователю не будет разрешено закрыть мастер, нажав кнопку Готово, если были какие-либо ожидающие проверки. Для этого у нас просто был счетчик ожидающих проверок и флаг, сигнализирующий о желании пользователя закрыть мастер. Основной алгоритм был:

  • Если инициируется новая проверка AJAX, увеличьте счетчик «в ожидании».
  • Когда вернется проверка AJAX, уменьшите счетчик «в ожидании».
  • Если при уменьшении счетчик ожидания достигает нуля, установите флажок «финиш»; если он установлен, завершите работу мастера.
  • Когда пользователь нажимает кнопку Готово, проверьте счетчик «в ожидании»; если это ноль, закончите волшебника; если оно ненулевое, установите флаг «финиш».

Таким образом, синхронизация может быть обработана только двумя переменными («в ожидании», «завершить»).

Я настоятельно не рекомендую использовать несколько флагов для каждой отдельной операции AJAX; конечный автомат обычно выходит из-под контроля, когда состояния отслеживаются с помощью нескольких переменных состояния. Старайтесь избегать этого, если это не является абсолютно необходимым.

Я также не предлагаю использовать setTimeout для произвольного ожидания, пока не будут выполнены требуемые условия. При описанном выше подходе со счетчиком ваш код будет реагировать на изменяющиеся условия, как только они меняются.

0 голосов
/ 21 июня 2009

Не думаю, что я полностью понял ваш вопрос, но вот некоторые мысли по решению проблем, которые вы можете иметь:)

Во-первых, я бы отключил кнопку открытия всплывающего окна при отправке вызова AJAX. затем, когда запрошенные данные поступят и все проверки пройдены, активируйте их снова. Вы можете сделать это с помощью счетчика: увеличивать его для каждого отправленного запроса, уменьшать его по мере поступления данных и проверки. активировать кнопку открытия всплывающего окна, когда данные поступают и счетчик равен нулю. это не позволяет пользователю нажимать кнопку открытия всплывающего окна, пока еще есть запросы на проверку.

вы можете использовать ту же технику для самих полей ввода: заблокировать поля ввода, ожидающие проверки, установив их только для чтения, разблокировать их, когда все будет сделано.

для предотвращения проблем, когда пользователь изменяет значения формы, пока вызов ajax еще не возвращен, у вас есть несколько вариантов:

  • использовать таймер для отправки запроса: каждый раз, когда происходит событие onchange, подождите x секунд перед отправкой запроса. если перед отправкой запроса ajax происходит другое событие onchange, сбросьте таймер. таким образом, несколько событий onchange с определенным таймфреймом вызывают только 1 ajax-запрос. это помогает снизить нагрузку.

  • вы можете вычислять и сохранять контрольные суммы для каждой позиции, поэтому, если происходит событие onchange, снова вычислите контрольные суммы и сравните их. Таким образом, вы узнаете, какие части действительно были изменены, избегая ненужных проверочных запросов.

также никогда не делайте ставок вовремя (если я правильно понял, что такое settimeout). х секунд может быть достаточно при нормальных обстоятельствах, но в худшем случае ...

0 голосов
/ 25 мая 2009

Установить флаги (переменные) для каждой группы проверок.

  • Установить флаг на 0.
  • Установите флаг в 1, когда проверка завершена для группы.
  • Когда пользователь нажимает кнопку, если все флаги 1, всплывающее окно.

Обратный вызов, о котором упоминал Джон, решит проблему «что вы будете делать, если они еще не все проверены?»


РЕДАКТИРОВАТЬ: Добавлено после уточнения:

Рассматривали ли вы добавление всплывающей кнопки с помощью методов DOM (легко) (или innerHTML, если хотите), после все проверено? Таким образом, ни одна опция не будет показана раньше времени. : D

Кроме того, вы проверяете, заблокировано ли всплывающее окно? Если это так, вы можете перейти либо к уведомлению пользователя о том, что его блокировщик блокирует редактор; или для автоматической загрузки вашего редактора в iframe; или загрузить редактор на главную страницу с помощью методов DOM (добавление documentFragment и т. д.).

Некоторые блокировщики дают пользователям возможность блокировать даже всплывающие окна, генерируемые при нажатии на ссылки (которые традиционно были недоступны для блокировщиков). Я бы подумал, что вам пригодится какой-нибудь метод резервного копирования или, по крайней мере, система предупреждений на месте.

НТН

0 голосов
/ 24 мая 2009

Допустим, под полями ввода вы подразумеваете только текстовые вводы, а не какие-либо флажки или комбоксы (я предполагаю, что вы пытаетесь сделать своего рода автозаполнение). Мой совет - использовать onkeyup и onkeydown.

var keypressed = false;

function onkeydown( )
{
   keypressed = true;
}

function onkeyup( )
{
  keypressed = false;
  setTimeout( function()
              { 
                 if (!keypressed) 
                    show_popup();
                 else 
                    setTimeout( this.calee,1000)
               }, 1000 );
}
0 голосов
/ 24 мая 2009

Если вы задали глобальную переменную и используете setTimeout, чтобы проверить, правильно ли она установлена. В зависимости от сложности ситуации вы можете использовать логическое значение, два логических значения, число с приращением или даже объект. Лично я хотел бы использовать объект так, как я знаю, который еще не был запущен. что-то вроде
var isDone = {username: 0, password: 0, password2: 0};

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...