Перестроить поведение окна подсказки

Я пытаюсь воссоздать поведение основного окна подсказки в JavaScript, чтобы я мог его стилизовать. По сути, я хочу иметь возможность вызывать функцию (window.vars.prompt), чтобы она запрашивала пользователя, а затем возвращала значение, введенное пользователем. Я хочу, чтобы все происходило синхронно, чтобы я мог вызвать это через функцию и вернуть его вызывающей стороне.

То, что у меня есть до сих пор, замораживает программу, а затем вылетает. Я знаю почему, но понятия не имею, как это исправить. Кто-нибудь это починит?

Спасибо!

(function () {
    window.vars.userHasResponded = false
    window.vars.userResponse = ""
    window.vars.prompt = function(displayMsg) {
        $(".input").html(`<div class='prompt'><h2>${displayMsg}</h2><div class = "input"><input id = "promptValue"/></div><div class = "promptContros"><button>ok</button><button>cancel</button></div></div>`)

        while (!window.vars.userHasResponded) {
            if (window.vars.userResponse)
                return window.vars.userResponse;
        }
    }
    window.vars.confirmPrompt = function() {
        $(".prompt").html("")
        window.vars.userResponse = $("#promptValue").val()
        window.vars.userHasResponded = window.vars.userResponse != "";
    }
})()

HTML для коробки хранится в div с классом Вход

почему цикл while не работает? Он выполняет итерацию и проверяет условие?

Jacob Schneider 18.06.2018 08:59

@JacobSchneider Ваш цикл while блокирует взаимодействие с браузером, это синхронно. Ваш браузер застрял в бесконечном цикле и зависает, пользователь ничего не может сделать

Justinas 18.06.2018 09:01
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
75
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

I'm looking at trying to recreate the behaviour of a basic prompt box in javascript...I want everything to happen synchronously, so that I can call it via a function and have it returned to the caller.

Вы не можете этого сделать. Обработчики prompt, alert, confirm и beforeunload - единственный синхронный пользовательский интерфейс в мире JavaScript на основе браузера, и вы не можете стилизовать их. Невозможно воспроизвести это поведение в собственном виджете пользовательского интерфейса.

Ваш собственный виджет имеют будет асинхронным.

В комментарии к заданному вами вопросу:

how come that while loop doesn't work?

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

Вместо этого возьмите свой prompt и возвратите обещание. Тогда использование этого в обычной функции выглядит так:

prompt(/*...*/)
    .then(result => {
        // ...use the result
    });

... или как это в async функция:

const result = await prompt(/*...*/);

(Обработка ошибок опущена для краткости.)

@JacobSchneider - Не совсем; принять асинхронную, управляемую событиями природу программирования на основе браузера не так уж и сложно. И в наши дни, если вы хотите писать синхронно выглядящий код, вы можете использовать async функции и await (напрямую нацеленные только на передовые движки JavaScript или через транспилирование).

T.J. Crowder 18.06.2018 09:03

Да, я просто новичок во всем, что касается async, и в этом немного хлопотно участвовать. Но я посмотрю.

Jacob Schneider 18.06.2018 09:04

I want everything to happen synchronously

К сожалению, это невозможно - сценаристы не могут писать свои собственные API-интерфейсы, которые в основном содержат блокировать, пока они не будут разрешены, без полного замораживания браузера, они могут только вызывать несколько специальных встроенных методов, которые обладают этим специфическим свойством. Как есть, поток вашего цикла while будет работать вечно, предотвращая запуск confirmPrompt. Поток никогда не заканчивается, и поэтому confirmPrompt никогда не запускается.

Попробуйте вместо этого использовать обещания. await, хотя и не синхронный, может выполнять смотрю более синхронно, чем при использовании .then.

Обещает, что это так. Спасибо.

Jacob Schneider 18.06.2018 09:01

Другие вопросы по теме