alert(msg) shows a message, confirm(msg) returns true or false, and prompt(msg, default) returns the typed string or null. The HTML Standard makes them pause the page: no timers, rendering or event handlers run until the user answers. They cannot be styled, and a sandboxed <iframe> without allow-modals suppresses them. Use <dialog> (<dialog> and popover, Baseline since March 2022); wrapped in a promise, it keeps the "ask and wait" flow without freezing the page.
<dialog id="ask"><form method="dialog">Delete 3 files?
<button value="no">Cancel</button> <button value="yes" autofocus>Delete</button></form></dialog>
<p id="out">Waiting for an answer...</p>
<script>
const dlg = document.querySelector('#ask');
const ask = () => new Promise((resolve) => {
dlg.addEventListener('close', () => resolve(dlg.returnValue === 'yes'), { once: true });
dlg.showModal();
});
ask().then((ok) => { document.querySelector('#out').textContent = `Confirmed: ${ok}`; });
</script>
A button in <form method="dialog"> closes the dialog and copies its value into returnValue; Esc leaves it empty, which counts as "no".