Skip to content

JavaScript 弹窗

什么是弹窗

弹窗(Popup)是浏览器中显示的小型对话框窗口,用于向用户显示信息、请求输入或获取确认。JavaScript 提供了几种创建弹窗的方法,这些方法都是 window 对象的方法。

弹窗的类型

JavaScript 中有三种基本类型的弹窗:

  1. 警告框(Alert Box):用于向用户显示信息,只有一个 "确定" 按钮
  2. 确认框(Confirm Box):用于获取用户的确认,有 "确定" 和 "取消" 按钮
  3. 提示框(Prompt Box):用于获取用户输入,有一个文本输入框和 "确定"、"取消" 按钮

警告框(Alert Box)

警告框用于向用户显示信息,用户必须点击 "确定" 按钮才能继续。

语法

javascript
window.alert(message);

参数

  • message:要在警告框中显示的文本

示例

javascript
// 基本警告框
window.alert("Hello, World!");

// 也可以省略 window.
alert("This is an alert box!");

// 多行文本
alert("Line 1\nLine 2\nLine 3");

// 变量和表达式
let name = "John";
alert(`Hello, ${name}!`);

// 函数中使用
function showAlert() {
  alert("Button clicked!");
}

// 绑定到按钮点击事件
document.getElementById("alert-btn").addEventListener("click", showAlert);

特点

  • 警告框只有一个 "确定" 按钮
  • 警告框会阻塞页面的其他操作,直到用户点击 "确定"
  • 警告框的样式由浏览器决定,无法自定义
  • 警告框不返回任何值

确认框(Confirm Box)

确认框用于获取用户的确认,用户可以选择 "确定" 或 "取消"。

语法

javascript
window.confirm(message);

参数

  • message:要在确认框中显示的文本

返回值

  • true:如果用户点击 "确定"
  • false:如果用户点击 "取消"

示例

javascript
// 基本确认框
let result = confirm("Are you sure?");
console.log("Confirm result:", result);

// 在条件语句中使用
if (confirm("Do you want to continue?")) {
  console.log("User clicked OK");
  // 执行确定操作
} else {
  console.log("User clicked Cancel");
  // 执行取消操作
}

// 函数中使用
function deleteItem() {
  if (confirm("Are you sure you want to delete this item?")) {
    console.log("Item deleted");
    // 执行删除操作
  } else {
    console.log("Delete cancelled");
    // 取消删除
  }
}

// 绑定到按钮点击事件
document.getElementById("delete-btn").addEventListener("click", deleteItem);

特点

  • 确认框有 "确定" 和 "取消" 两个按钮
  • 确认框会阻塞页面的其他操作,直到用户点击按钮
  • 确认框的样式由浏览器决定,无法自定义
  • 确认框返回布尔值,表示用户的选择

提示框(Prompt Box)

提示框用于获取用户输入,用户可以在文本框中输入内容,然后点击 "确定" 或 "取消"。

语法

javascript
window.prompt(message, defaultText);

参数

  • message:要在提示框中显示的文本
  • defaultText:(可选)文本框中的默认值

返回值

  • 字符串:如果用户点击 "确定",返回文本框中的内容
  • null:如果用户点击 "取消"

示例

javascript
// 基本提示框
let name = prompt("What is your name?");
console.log("Name:", name);

// 带默认值的提示框
let age = prompt("How old are you?", "18");
console.log("Age:", age);

// 在条件语句中使用
let userInput = prompt("Enter a number:");
if (userInput !== null) {
  let number = parseInt(userInput);
  if (!isNaN(number)) {
    console.log("You entered:", number);
    // 处理输入
  } else {
    console.log("Invalid number");
    // 处理无效输入
  }
} else {
  console.log("User cancelled");
  // 处理取消
}

// 函数中使用
function getUserInfo() {
  let name = prompt("What is your name?");
  let email = prompt("What is your email?");

  if (name && email) {
    console.log("User info:", { name, email });
    // 处理用户信息
  } else {
    console.log("User info not provided");
    // 处理未提供信息的情况
  }
}

// 绑定到按钮点击事件
document.getElementById("prompt-btn").addEventListener("click", getUserInfo);

特点

  • 提示框有一个文本输入框和 "确定"、"取消" 两个按钮
  • 提示框会阻塞页面的其他操作,直到用户点击按钮
  • 提示框的样式由浏览器决定,无法自定义
  • 提示框返回用户输入的字符串或 null

自定义弹窗

浏览器内置的弹窗样式简单且无法自定义,对于需要更美观、更灵活的弹窗,可以创建自定义弹窗。

使用 HTML、CSS 和 JavaScript 创建自定义弹窗

1. 基本结构

html
<!-- HTML 结构 -->
<div id="custom-modal" class="modal">
  <div class="modal-content">
    <span class="close">&times;</span>
    <h2 id="modal-title">Modal Title</h2>
    <p id="modal-message">Modal message goes here.</p>
    <div class="modal-buttons">
      <button id="modal-ok">OK</button>
      <button id="modal-cancel">Cancel</button>
    </div>
  </div>
</div>

<button id="open-modal">Open Modal</button>

2. CSS 样式

css
/* 弹窗背景 */
.modal {
  display: none; /* 默认隐藏 */
  position: fixed; /* 固定定位 */
  z-index: 1; /* 置于顶层 */
  left: 0;
  top: 0;
  width: 100%; /* 全屏宽度 */
  height: 100%; /* 全屏高度 */
  overflow: auto; /* 允许滚动 */
  background-color: rgba(0, 0, 0, 0.4); /* 半透明黑色背景 */
}

/* 弹窗内容 */
.modal-content {
  background-color: #fefefe;
  margin: 15% auto; /* 15% 从顶部,水平居中 */
  padding: 20px;
  border: 1px solid #888;
  width: 80%; /* 宽度 */
  max-width: 500px; /* 最大宽度 */
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

/* 关闭按钮 */
.close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
  cursor: pointer;
}

.close:hover,
.close:focus {
  color: black;
  text-decoration: none;
}

/* 弹窗标题 */
#modal-title {
  margin-top: 0;
}

/* 弹窗按钮 */
.modal-buttons {
  margin-top: 20px;
  text-align: right;
}

.modal-buttons button {
  padding: 8px 16px;
  margin-left: 10px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

#modal-ok {
  background-color: #4caf50;
  color: white;
}

#modal-cancel {
  background-color: #f44336;
  color: white;
}

#modal-ok:hover {
  background-color: #45a049;
}

#modal-cancel:hover {
  background-color: #da190b;
}

3. JavaScript 逻辑

javascript
// 获取弹窗元素
const modal = document.getElementById("custom-modal");
const openModalBtn = document.getElementById("open-modal");
const closeBtn = document.getElementsByClassName("close")[0];
const okBtn = document.getElementById("modal-ok");
const cancelBtn = document.getElementById("modal-cancel");
const modalTitle = document.getElementById("modal-title");
const modalMessage = document.getElementById("modal-message");

// 打开弹窗
function openModal(title, message) {
  modalTitle.textContent = title;
  modalMessage.textContent = message;
  modal.style.display = "block";
}

// 关闭弹窗
function closeModal() {
  modal.style.display = "none";
}

// 点击打开弹窗按钮
openModalBtn.addEventListener("click", () => {
  openModal("Welcome", "This is a custom modal box!");
});

// 点击关闭按钮
closeBtn.addEventListener("click", closeModal);

// 点击确定按钮
okBtn.addEventListener("click", () => {
  console.log("OK clicked");
  closeModal();
});

// 点击取消按钮
cancelBtn.addEventListener("click", () => {
  console.log("Cancel clicked");
  closeModal();
});

// 点击弹窗外部关闭
window.addEventListener("click", (event) => {
  if (event.target === modal) {
    closeModal();
  }
});

// 按 ESC 键关闭
window.addEventListener("keydown", (event) => {
  if (event.key === "Escape" && modal.style.display === "block") {
    closeModal();
  }
});

使用第三方库创建自定义弹窗

对于更复杂的弹窗需求,可以使用第三方库,如 Bootstrap Modal、SweetAlert2 等。

SweetAlert2 示例

html
<!-- 引入 SweetAlert2 CSS 和 JS -->
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js"></script>

<button id="swal-alert">SweetAlert Alert</button>
<button id="swal-confirm">SweetAlert Confirm</button>
<button id="swal-prompt">SweetAlert Prompt</button>
javascript
// 基本警告
document.getElementById("swal-alert").addEventListener("click", () => {
  Swal.fire("Hello, World!");
});

// 确认框
document.getElementById("swal-confirm").addEventListener("click", () => {
  Swal.fire({
    title: "Are you sure?",
    text: "You won't be able to revert this!",
    icon: "warning",
    showCancelButton: true,
    confirmButtonColor: "#3085d6",
    cancelButtonColor: "#d33",
    confirmButtonText: "Yes, delete it!",
  }).then((result) => {
    if (result.isConfirmed) {
      Swal.fire("Deleted!", "Your file has been deleted.", "success");
    }
  });
});

// 提示框
document.getElementById("swal-prompt").addEventListener("click", () => {
  Swal.fire({
    title: "Enter your name",
    input: "text",
    inputPlaceholder: "Your name",
    showCancelButton: true,
    inputValidator: (value) => {
      if (!value) {
        return "You need to enter your name!";
      }
    },
  }).then((result) => {
    if (result.isConfirmed) {
      Swal.fire(`Hello, ${result.value}!`);
    }
  });
});

弹窗的最佳实践

1. 谨慎使用内置弹窗

浏览器内置的弹窗(alert、confirm、prompt)会阻塞页面的其他操作,可能会影响用户体验。建议:

  • 只在必要时使用内置弹窗
  • 对于非关键信息,使用自定义弹窗或通知
  • 避免在循环中使用弹窗
  • 避免在页面加载时自动显示弹窗

2. 提供清晰的信息

弹窗中的信息应该清晰、简洁、直接:

  • 使用简单明了的语言
  • 避免使用技术术语
  • 对于确认框,明确说明用户操作的后果
  • 对于提示框,提供合理的默认值

3. 处理用户输入

对于提示框,应该验证和处理用户输入:

  • 检查用户是否点击了 "取消"
  • 验证输入内容的有效性
  • 处理空输入的情况
  • 转换输入为适当的数据类型
javascript
// 处理提示框输入
function getValidatedInput() {
  let input;
  let isValid = false;

  while (!isValid) {
    input = prompt("Enter a number between 1 and 10:");

    // 检查是否取消
    if (input === null) {
      console.log("User cancelled");
      return null;
    }

    // 转换为数字
    const number = parseInt(input);

    // 验证输入
    if (!isNaN(number) && number >= 1 && number <= 10) {
      isValid = true;
      return number;
    } else {
      alert("Please enter a valid number between 1 and 10.");
    }
  }
}

// 示例:使用验证后的输入
const userNumber = getValidatedInput();
if (userNumber !== null) {
  console.log("Valid number entered:", userNumber);
}

4. 考虑可访问性

弹窗应该对所有用户都可访问,包括使用屏幕阅读器的用户:

  • 为弹窗添加适当的 ARIA 属性
  • 确保弹窗可以通过键盘操作
  • 提供明确的关闭机制
  • 确保弹窗内容与背景有足够的对比度

5. 测试不同浏览器

不同浏览器对内置弹窗的实现可能略有不同,建议在主要浏览器中测试弹窗的行为。

弹窗的替代方案

对于不需要用户立即响应的信息,可以使用以下替代方案:

1. 通知(Notifications)

浏览器的 Notification API 允许向用户发送系统级通知:

javascript
// 检查通知权限
function requestNotificationPermission() {
  if ("Notification" in window) {
    Notification.requestPermission().then((permission) => {
      if (permission === "granted") {
        console.log("Notification permission granted");
        // 发送通知
        sendNotification();
      } else {
        console.log("Notification permission denied");
      }
    });
  }
}

// 发送通知
function sendNotification() {
  if ("Notification" in window && Notification.permission === "granted") {
    new Notification("Hello!", {
      body: "This is a notification",
      icon: "icon.png",
    });
  }
}

// 请求权限并发送通知
document
  .getElementById("notification-btn")
  .addEventListener("click", requestNotificationPermission);

2. 页面内通知

在页面内显示通知,而不是使用弹窗:

html
<!-- HTML 结构 -->
<div id="notification" class="notification">
  <span id="notification-message"></span>
  <button id="notification-close">&times;</button>
</div>

<button id="show-notification">Show Notification</button>
css
/* CSS 样式 */
.notification {
  display: none;
  position: fixed;
  top: 20px;
  right: 20px;
  background-color: #333;
  color: white;
  padding: 15px;
  border-radius: 5px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  min-width: 200px;
}

.notification.show {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

#notification-close {
  background: none;
  border: none;
  color: white;
  font-size: 20px;
  cursor: pointer;
  margin-left: 10px;
}
javascript
// JavaScript 逻辑
const notification = document.getElementById("notification");
const notificationMessage = document.getElementById("notification-message");
const notificationClose = document.getElementById("notification-close");
const showNotificationBtn = document.getElementById("show-notification");

// 显示通知
function showNotification(message, duration = 3000) {
  notificationMessage.textContent = message;
  notification.classList.add("show");

  // 自动关闭
  setTimeout(() => {
    hideNotification();
  }, duration);
}

// 隐藏通知
function hideNotification() {
  notification.classList.remove("show");
}

// 点击关闭按钮
notificationClose.addEventListener("click", hideNotification);

// 点击显示通知按钮
showNotificationBtn.addEventListener("click", () => {
  showNotification("This is a page notification!");
});

3. 工具提示(Tooltips)

对于简短的提示信息,可以使用工具提示:

html
<!-- HTML 结构 -->
<button class="tooltip-container">
  Hover me
  <span class="tooltip">This is a tooltip</span>
</button>
css
/* CSS 样式 */
.tooltip-container {
  position: relative;
  display: inline-block;
}

.tooltip {
  visibility: hidden;
  width: 120px;
  background-color: #333;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 5px;
  position: absolute;
  z-index: 1;
  bottom: 125%;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
  transition: opacity 0.3s;
}

.tooltip-container:hover .tooltip {
  visibility: visible;
  opacity: 1;
}

总结

JavaScript 提供了三种基本类型的弹窗:警告框、确认框和提示框。这些弹窗都是 window 对象的方法,用于向用户显示信息、获取确认或输入。

虽然内置弹窗使用简单,但它们的样式和功能有限,并且会阻塞页面操作。对于更复杂的需求,可以使用自定义弹窗或第三方库。

在使用弹窗时,应该遵循最佳实践,提供清晰的信息,处理用户输入,考虑可访问性,并测试不同浏览器的行为。对于不需要用户立即响应的信息,可以考虑使用通知、页面内通知或工具提示等替代方案。