Пользовательский prompt

Описание

После небольшой дискуссии решил создать собственную версию window.prompt(). Моя версия выглядит так:

class Manager {
  static async prompt(message) {
    const dialog = document.body.appendChild(document.createElement(`dialog`));
    dialog.appendChild(document.createElement(`span`)).innerText = message;
    const input = dialog.appendChild(document.createElement(`input`));
    input.type = `text`;
    const promise = new Promise((resolve) => {
      dialog.addEventListener(`click`, (event) => {
        if (event.target == dialog) {
          resolve(input.value);
          dialog.remove()
        }
      });
    });
    dialog.showModal();
    return await promise;
  }
}

document.write(Manager.prompt(`Input text`));
* {
  margin: 0;
  padding: 0;
  border: none;
  outline: none;
}

body {
  background-color: rgb(25, 25, 25);
  color: rgb(255, 255, 255);
}

body * {
  background-color: inherit;
  color: inherit;
  border-radius: 8px;
}

dialog {
  background-color: rgb(50, 50, 50);
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: auto;
  padding: 8px;
}

input {
  background-color: rgb(25, 25, 25);
  padding: 8px;
}

dialog::backdrop {
  background-color: rgba(0, 0, 0, 50%)
}

После ввода надо нажимать вне окна и значение передается. Проблема в том, что, чтобы я не делал, где бы я не пимал async и await передается Promise<String>.

Вопрос

Но что мне делать, чтобы передавалась просто String, как во встроенной версии.

Уточнение

Возможно проблема в том, что я неправильно реализовал async и await, поскольку немного работал с ними и не все тонкости знаю. Так что с удовольствием приму и статью где, есть решение моей проблемы и объяснения - почему так происходит.


Ответы (1 шт):

Автор решения: EzioMercer

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

class Manager {
  static prompt(message, callBack) {
    const dialog = document.createElement('dialog');
    const span = document.createElement('span');
    const input = document.createElement('input');
    
    span.innerText = message;
    input.type = 'text';
    
    dialog.addEventListener('click', (event) => {
      if (event.target !== dialog) return;

      callBack(input.value);
      dialog.remove();
    });
    
    dialog.append(span, input);
    document.body.append(dialog);
    
    dialog.showModal();
  }
}

Manager.prompt('Input text', (ans) => document.write(ans));
* {
  margin: 0;
  padding: 0;
  border: none;
  outline: none;
}

body {
  //background-color: rgb(25, 25, 25);
  //color: rgb(255, 255, 255);
}

body * {
  background-color: inherit;
  color: inherit;
  border-radius: 8px;
}

dialog {
  background-color: rgb(50, 50, 50);
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: auto;
  padding: 8px;
}

input {
  background-color: rgb(25, 25, 25);
  padding: 8px;
}

dialog::backdrop {
  background-color: rgba(0, 0, 0, 50%)
}

Как только вы начнёте писать async и/или использовать Promise-ы, там надо будет всё это дело вызывать в асинхронной функции или использовать синтаксис then. Про подробное объяснение, почему без этого нельзя обойтись, можете почитать мой ответ

→ Ссылка