问题描述
我正在尝试根据用户单击的按钮从自定义确认框获取返回值。不知道如何异步处理。
确认窗口的模板是预先制作的,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
语句没有执行您期望的等待。固定代码有三处变化。
-
confirmation_box
返回一个Promise
,其中包含 Promise 中的所有代码。 -
return 0
和return 1
已更改为resolve(0)
和resolve(1)
-
正如 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>