Короткий ответ - нет, вы не сможете сохранить свой код синхронным. И вот почему:
- Для того, чтобы это было синхронно, исполняемый в данный момент скрипт должен будет дождаться, пока пользователь предоставит ввод, а затем продолжить.
- Пока существует исполняемый скрипт, пользователь не может взаимодействовать с пользовательским интерфейсом. На самом деле, пользовательский интерфейс даже не обновляется, пока не завершится выполнение скрипта.
- Если сценарий не может продолжаться до тех пор, пока пользователь не предоставит ввод, и пользователь не сможет предоставить ввод, пока сценарий не будет завершен, самым близким из всех, что вы когда-либо получите, является зависший браузер.
Чтобы проиллюстрировать это поведение, отладьте свой код и установите точку останова на строке, следующей за строкой, которая изменяет пользовательский интерфейс:
$("body").css("backgroundColor", "red");
var x = 1; // break on this line
Обратите внимание, что фон вашей страницы еще не красный. Он не изменится на красный, пока вы не возобновите выполнение и скрипт не завершит выполнение. Вы также не можете нажимать ссылки на своей странице, когда выполнение сценария приостановлено с помощью отладчика.
Существует исключение из этого правила для alert()
и confirm()
. Это элементы управления браузера, и они обрабатываются иначе, чем элементы пользовательского интерфейса веб-страницы.
Хорошая новость заключается в том, что преобразование кода не должно быть очень сложным. Предположительно, ваш код в настоящее время выглядит примерно так:
if (confirm("continue?")) {
// several lines of code if yes
}
else {
// several lines of code if no
}
// several lines of code finally
Ваша асинхронная версия может создать функцию ifConfirm(text, yesFn, noFn, finallyFn)
, и ваш код будет выглядеть примерно так же:
ifConfirm("continue?", function () {
// several lines of code if yes
},
function () {
// several lines of code if no
},
function () {
// several lines of code finally
});
Редактировать: В ответ на дополнительный пример, который вы добавили в свой вопрос, к сожалению, этот код придется реорганизовать. Просто невозможно иметь синхронные пользовательские диалоги подтверждения. Чтобы использовать настраиваемое диалоговое окно подтверждения в сценарии, где событие необходимо продолжить или отменить, вам просто нужно всегда отменять событие и имитировать событие в обратном вызове yesFn
.
Например, ссылка:
$("a[href]").click(function (e) {
e.preventDefault();
var link = this.href;
ifConfirm("Are you sure you want to leave this awesome page?", function () {
location.href = link;
});
});
Или, форма:
$("form").submit(function (e) {
e.preventDefault();
var form = this;
ifConfirm("Are you sure you're ready to submit this form?", function () {
form.submit();
});
});