比较不同类型的原生 JavaScript 弹窗

Avatar of Elliot Goldman
Elliot Goldman on

DigitalOcean 为您的旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

JavaScript 有一系列内置的弹窗 API,用于显示特殊的 UI 以供用户交互。最有名的

alert("Hello, World!");

这个 UI 在不同的浏览器中会有所不同,但通常你会看到一个小窗口弹出到页面正中央,以一种非常醒目的方式显示你刚刚传递的消息。 以下是 Firefox 和 Chrome 的截图

Firefox(左)和 Chrome(右)中的原生弹窗。请注意,Firefox 中的额外 UI 阻止了其他对话框触发同一个对话框多次。您还可以看到 Chrome 如何固定在窗口顶部。

有一个重要的问题您应该提前了解

JavaScript 弹窗是 阻塞 的。

当弹窗打开时,整个页面实质上 停止 了。在弹窗打开时,您无法与页面上的任何内容进行交互 - 这正是“模态框”的意义,但这也是您应该非常清楚的用户体验注意事项。关键是,在弹窗打开时,没有其他主线程 JavaScript 代码在运行,这可能会(也可能已经)不必要地阻止您的网站执行需要进行的操作。

十之八九,您最好重新设计架构,避免使用这种过于强硬的停止一切行为。浏览器对原生 JavaScript 警告的实现方式也使得您无法进行任何设计控制。您无法控制它们出现在页面上的 位置 或者它们到达时 外观除非您绝对需要它们的完全阻塞特性,否则几乎总是使用您自己设计的自定义用户界面更好,这样您就可以根据用户的需求定制体验。

现在我们已经说明了这一点,让我们看看每个原生弹窗。

window.alert();

window.alert("Hello World");

<button onclick="alert('Hello, World!');">Show Message</button>

const button = document.querySelectorAll("button");
button.addEventListener("click", () => {
  alert("Text of button: " + button.innerText);
});

查看 CodePen 上的示例
alert("Example");
,作者是 Elliot KG (@ElliotKG)
CodePen 上。

用途:显示简单的消息或调试变量的值。

工作原理:此函数接受一个字符串,并在弹窗中将其呈现给用户,弹窗中有一个带有“确定”标签的按钮。您只能更改消息,而不能更改其他任何方面,例如按钮的显示文字。

替代方案:与其他警告类似,如果您需要向用户显示消息,最好以一种专门针对您想要实现的目标的方式来实现。

如果您尝试调试变量的值,请考虑使用 console.log("Value of variable: ", variable); 并查看控制台。

window.confirm();

window.confirm("Are you sure?");

<button onclick="confirm('Would you like to play a game?');">Ask Question</button>

let answer = window.confirm("Do you like cats?");
if (answer) {
  // User clicked OK
} else {
  // User clicked Cancel
}

查看 CodePen 上的示例
confirm("Example");
,作者是 Elliot KG (@ElliotKG)
CodePen 上。

用途:“您确定吗?” - 类型的消息,用于查看用户是否真的想要完成他们发起的操作。

工作原理:您可以提供自定义消息,弹窗会给您“确定”或“取消”选项,您可以使用返回值查看返回的是什么。

替代方案:这是一种非常干扰用户的方式。正如 Aza Raskin 所说

…也许您根本不想使用警告。

有很多方法可以询问用户确认某件事。可能一个带有 <button>Confirm</button> 的清晰 UI,连接到您需要它完成的操作。

window.prompt();

window.prompt("What’s your name?"); 

let answer = window.prompt("What is your favorite color?");
// answer is what the user typed in, if anything

查看 CodePen 上的示例
prompt("Example?", "Default Example");
,作者是 Elliot KG (@ElliotKG)
CodePen 上。

用途:提示用户输入。您提供一个字符串(可能格式化为问题),用户会看到一个带有该字符串的弹窗,一个可以输入的输入框,以及“确定”和“取消”按钮。

工作原理:如果用户点击“确定”,您将获得他们在输入框中输入的内容。如果他们什么也没输入并点击“确定”,您将获得一个空字符串。如果他们选择“取消”,返回值将是 null

替代方案:与所有其他原生 JavaScript 警告一样,它不允许您设置警告框的样式或位置。最好使用 <form> 从用户那里获取信息。这样您就可以提供更多上下文和有目的的设计。

window.onbeforeunload();

window.addEventListener("beforeunload", () => {
  // Standard requires the default to be cancelled.
  event.preventDefault();
  // Chrome requires returnValue to be set (via MDN)
  event.returnValue = '';
});

查看 CodePen 上的示例
beforeunload 事件示例
,作者是 Chris Coyier (@chriscoyier)
CodePen 上。

用途:在用户离开页面之前警告他们。这听起来可能很烦人,但它并不总是被烦人地使用。它被用于一些需要显式保存工作的网站。如果用户还没有保存他们的工作并且即将离开,您可以使用它来警告他们。如果他们 *已经* 保存了他们的工作,您应该删除它。

工作原理:如果您将 beforeunload 事件附加到窗口(并执行上面代码段中显示的额外操作),当用户尝试离开页面时,他们会看到一个弹窗,询问他们是否要“离开”或“取消”。离开网站可能是因为用户点击了一个链接,但也可能是点击浏览器的刷新或后退按钮的结果。您无法自定义消息。

MDN 警告,一些浏览器要求与页面进行交互才能使它正常工作

为了防止出现不必要的弹窗,一些浏览器不会显示在 beforeunload 事件处理程序中创建的提示,除非与页面进行了交互。此外,有些浏览器根本不显示它们。

替代方案:我暂时没有想到其他替代方案。如果用户可能会丢失工作,您就必须使用它。如果他们选择留在页面,您应该清楚地告诉他们应该做什么,以确保安全离开。

无障碍性

原生 JavaScript 警告曾经在无障碍性领域不受欢迎,但现在看来,屏幕阅读器在处理它们的方式上变得更加智能了。 根据宾夕法尼亚州立大学无障碍性网站

以前不鼓励使用警告框,但它们实际上在现代屏幕阅读器中是可访问的。

在创建您自己的模态框时,务必考虑无障碍性,但有一些很棒的资源,例如 Ire Aderinokun 的这篇文章,可以为您指明正确的方向。

通用替代方案

原生 JavaScript 弹窗有很多替代方案,例如自己编写弹窗,使用模态窗口库以及使用警告库。请记住,我们所介绍的内容无法完全阻止 JavaScript 的执行和用户交互,但有些可以使背景变灰,并迫使用户在继续操作之前与模态框进行交互,从而接近这一目标。

您可能想看看 HTML 的原生 <dialog> 元素。Chris 最近 动手尝试过 它。它很有吸引力,但显然 存在 一些重大的可访问性问题。我不确定自己构建一个会更好还是更糟,因为处理模态是一个非常不平凡的交互元素。一些 UI 库,比如 Bootstrap,提供了模态,但可访问性很大程度上仍然掌握在您手中。您可能需要看看类似 a11y-dialog 的项目。

总结

使用 Web 平台的内置 API 似乎是正确的做法——您无需发送大量的 JavaScript 代码来复制功能,而是使用我们已经内置的功能。但这里存在着严重的限制、用户体验问题和性能问题,这些问题都对使用原生 JavaScript 弹出框不利。了解它们是什么以及如何使用它们很重要,但您在生产网站上可能不会经常使用它们。