如何从自定义确认框中获取返回值

问题描述

我正在尝试根据用户单击的按钮从自定义确认框获取返回值。不知道如何异步处理。

确认窗口的模板是预先制作的,confirmation_Box() 将文本分配给指定的元素。

如果用户单击是,我想返回 1/true 的值,这将允许我继续下一步。如果点击否,确认窗口将简单地关闭并且代码停在那里。

async function confirmation_Box(msg = 'Are you sure?',false_btn = 'No',true_btn = 'Yes') {

  let confirmation_modal = document.getElementById('overlay');
  let true_el = confirmation_modal.querySelector('.true_btn');
  let false_el = confirmation_modal.querySelector('.false_btn');

  // assign text to elements
  confirmation_modal.querySelector('#confirmation_msg').textContent = msg;
  true_el.textContent = true_btn;
  false_el.textContent = false_btn;

  confirmation_modal.classList.add('show');

  true_el.addEventListener('click',await
    function() {
      confirmation_modal.classList.remove('show');
      return 1;
    });

  false_el.addEventListener('click',await
    function() {
      confirmation_modal.classList.remove('show');
      return 0;
    });
}


async function delete_demo() {
  let result = await confirmation_Box('are you sure you want to delete this?');
  console.log(`Confirmation result ${result}`);

  if (result) {
    document.getElementById('demo_text').remove();
  }


}
body {
  height: 100vh;
  display: -ms-grid;
  display: grid;
  place-content: center;
}

#overlay {
  top: 0;
  left: 0;
  opacity: 0;
  width: 100%;
  height: 100%;
  display: -ms-grid;
  display: grid;
  position: fixed;
  visibility: hidden;
  place-content: center;
  background: rgba(0,0.5);
}

#overlay.show {
  opacity: 1;
  visibility: visible;
}

.modal {
  padding: 10px;
  background: #fff;
  border: 1px solid #000;
}
<body>
  <div class="container">

    <p id='demo_text'>Demo text</p>

    <button onclick='delete_demo()'>Delete Demo</button>


    <div id="overlay">
      <div class="modal">
        <p id="confirmation_msg"></p>

        <div>
          <button class="false_btn"></button>
          <button class="true_btn"></button>
        </div>
      </div>
    </div>
  </div>

</body>

解决方法

你就快到了。

问题在于 confirmation_box 函数不返回 Promise,因此您的 await confirmation_box 语句没有执行您期望的等待。固定代码有三处变化。

  1. confirmation_box 返回一个 Promise,其中包含 Promise 中的所有代码。

  2. return 0return 1 已更改为 resolve(0)resolve(1)

  3. 正如 Barmar 所说,当您不想要多个事件侦听器时,不要在可能循环的任何内容中使用 addEventListener。我只是将其更改为 onclick,因为它使用了 resolve 区域内可用的 Promise 函数。

这是固定代码:

async function confirmation_box(msg = 'Are you sure?',false_btn = 'No',true_btn = 'Yes') {
    return new Promise(function(resolve){
      let confirmation_modal = document.getElementById('overlay');
      let true_el = confirmation_modal.querySelector('.true_btn');
      let false_el = confirmation_modal.querySelector('.false_btn');

      // assign text to elements
      confirmation_modal.querySelector('#confirmation_msg').textContent = msg;
      true_el.textContent = true_btn;
      false_el.textContent = false_btn;

      confirmation_modal.classList.add('show');

      true_el.onclick = function() {
          confirmation_modal.classList.remove('show');
          resolve(1);
        };

      false_el.onclick = function() {
          confirmation_modal.classList.remove('show');
          resolve(0);
        };
    });
}


async function delete_demo() {
  let result = await confirmation_box('are you sure you want to delete this?');
  console.log(`Confirmation result ${result}`);

  if (result) {
    document.getElementById('demo_text').remove();
  }


}
body {
  height: 100vh;
  display: -ms-grid;
  display: grid;
  place-content: center;
}

#overlay {
  top: 0;
  left: 0;
  opacity: 0;
  width: 100%;
  height: 100%;
  display: -ms-grid;
  display: grid;
  position: fixed;
  visibility: hidden;
  place-content: center;
  background: rgba(0,0.5);
}

#overlay.show {
  opacity: 1;
  visibility: visible;
}

.modal {
  padding: 10px;
  background: #fff;
  border: 1px solid #000;
}
<body>
  <div class="container">

    <p id='demo_text'>Demo text</p>

    <button onclick='delete_demo()'>Delete Demo</button>


    <div id="overlay">
      <div class="modal">
        <p id="confirmation_msg"></p>

        <div>
          <button class="false_btn"></button>
          <button class="true_btn"></button>
        </div>
      </div>
    </div>
  </div>
</body>