专业的编程技术博客社区

网站首页 > 博客文章 正文

如何使用JavaScript实现Prompt弹窗?

baijin 2025-06-08 19:15:33 博客文章 4 ℃ 0 评论

在 JavaScript语言 中,有两种方式可以实现 Prompt 弹窗,一种方式为使用浏览器内置的原生 prompt() 函数,也可以通过自定义 DOM 元素和 CSS 实现自定义输入弹窗。下文为您详细介绍这两种方式:


一、原生prompt()方法

此方法为 JavaScript 内置的最简单方式,直接调用 prompt() 函数即可。

示例代码:

const name = prompt('请输入你的名字:', '默认值');

if (name !== null) {
  // 用户点击了"确定"
  console.log(`你好,${name || '匿名用户'}!`);
} else {
  // 用户点击了"取消"
  console.log('操作已取消');
}

特点:

  1. 简单易用:无需额外代码,直接调用。
  2. 阻塞页面:弹窗显示时,用户无法操作页面其他元素,直到点击「确定」或「取消」。
  3. 样式固定:样式由浏览器决定,无法自定义。

二、自定义 Prompt 弹窗

通过创建 DOM 元素、添加 CSS 样式和 JavaScript 交互逻辑,可以实现完全自定义的 Prompt 弹窗。

示例代码:

<!DOCTYPE html>
<html>
<head>
  <style>
    /* 自定义 Prompt 弹窗样式 */
    .custom-prompt {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 9999;
    }

    .prompt-content {
      background-color: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
      max-width: 400px;
      width: 90%;
    }

    .prompt-message {
      margin-bottom: 15px;
      font-size: 16px;
    }

    .prompt-input {
      width: 100%;
      padding: 10px;
      margin-bottom: 15px;
      border: 1px solid #ddd;
      border-radius: 4px;
      box-sizing: border-box;
    }

    .prompt-buttons {
      display: flex;
      justify-content: flex-end;
      gap: 10px;
    }

    .prompt-button {
      padding: 10px 20px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 14px;
    }

    .prompt-ok {
      background-color: #007BFF;
      color: white;
    }

    .prompt-cancel {
      background-color: #f8f9fa;
      color: #333;
      border: 1px solid #ddd;
    }
  </style>
</head>
<body>

<button onclick="showCustomPrompt('请输入你的名字:', '默认值', handleInput)">
  显示自定义 Prompt
</button>

<script>
  // 自定义 Prompt 函数
  function showCustomPrompt(message, defaultValue, callback) {
    // 创建遮罩层
    const overlay = document.createElement('div');
    overlay.className = 'custom-prompt';
    
    // 创建弹窗内容
    const content = document.createElement('div');
    content.className = 'prompt-content';
    
    // 添加消息
    const messageElement = document.createElement('div');
    messageElement.className = 'prompt-message';
    messageElement.textContent = message;
    
    // 添加输入框
    const input = document.createElement('input');
    input.className = 'prompt-input';
    input.type = 'text';
    input.value = defaultValue || '';
    
    // 添加按钮容器
    const buttonsContainer = document.createElement('div');
    buttonsContainer.className = 'prompt-buttons';
    
    // 添加"确定"按钮
    const okButton = document.createElement('button');
    okButton.className = 'prompt-button prompt-ok';
    okButton.textContent = '确定';
    okButton.onclick = function() {
      callback(input.value); // 传递输入值给回调函数
      document.body.removeChild(overlay);
    };
    
    // 添加"取消"按钮
    const cancelButton = document.createElement('button');
    cancelButton.className = 'prompt-button prompt-cancel';
    cancelButton.textContent = '取消';
    cancelButton.onclick = function() {
      callback(null); // 传递 null 表示取消
      document.body.removeChild(overlay);
    };
    
    // 组装元素
    buttonsContainer.appendChild(cancelButton);
    buttonsContainer.appendChild(okButton);
    content.appendChild(messageElement);
    content.appendChild(input);
    content.appendChild(buttonsContainer);
    overlay.appendChild(content);
    
    // 添加到页面
    document.body.appendChild(overlay);
    
    // 自动聚焦输入框
    input.focus();
  }

  // 处理输入结果的回调函数
  function handleInput(value) {
    if (value !== null) {
      alert(`你输入的名字是:${value || '未输入内容'}`);
    } else {
      alert('操作已取消');
    }
  }
</script>

</body>
</html>

特点:

  1. 完全自定义:可以自由设计样式、动画和交互效果。
  2. 非阻塞页面:用户可以同时操作页面其他元素(如需阻塞,可添加相应逻辑)。
  3. 更灵活的功能:例如支持不同类型的输入框(文本、数字、密码等)、自定义验证逻辑。

三、基于 Promise 的现代 Prompt 弹窗

使用 Promise 实现更优雅的异步调用方式,以规避回调地狱困境。

示例代码:

<!DOCTYPE html>
<html>
<head>
<style>
/* 弹窗样式 */
.prompt-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

.modal-content {
  background: white;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  max-width: 400px;
  width: 90%;
  overflow: hidden;
}

.modal-header {
  padding: 16px;
  border-bottom: 1px solid #eee;
  font-size: 18px;
  font-weight: bold;
}

.modal-body {
  padding: 16px;
}

.modal-input {
  width: 100%;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  margin-top: 8px;
}

.modal-footer {
  padding: 12px 16px;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  background: #f9f9f9;
}

.modal-button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
}

.button-confirm {
  background: #165DFF;
  color: white;
}

.button-cancel {
  background: #f0f0f0;
  color: #333;
}
</style>
</head>
<body>

<button onclick="promptAction()">
  显示高级 Prompt
</button>

<script>
// 自定义 Prompt 弹窗(使用 Promise)
function customPrompt(options) {
  // 设置默认选项
  const defaults = {
    title: '输入提示',
    message: '请输入内容:',
    defaultValue: '',
    placeholder: '',
    confirmText: '确定',
    cancelText: '取消',
    inputType: 'text', // 可选: text, number, password
    onConfirm: () => {},
    onCancel: () => {}
  };
  
  const opts = { ...defaults, ...options };
  
  return new Promise((resolve) => {
    // 创建遮罩层
    const modal = document.createElement('div');
    modal.className = 'prompt-modal';
    
    // 创建弹窗内容
    const content = document.createElement('div');
    content.className = 'modal-content';
    
    // 添加标题
    const header = document.createElement('div');
    header.className = 'modal-header';
    header.textContent = opts.title;
    
    // 添加消息和输入框
    const body = document.createElement('div');
    body.className = 'modal-body';
    
    const message = document.createElement('div');
    message.textContent = opts.message;
    
    const input = document.createElement('input');
    input.className = 'modal-input';
    input.type = opts.inputType;
    input.value = opts.defaultValue;
    input.placeholder = opts.placeholder;
    
    // 添加按钮区域
    const footer = document.createElement('div');
    footer.className = 'modal-footer';
    
    // 添加确认按钮
    const confirmBtn = document.createElement('button');
    confirmBtn.className = 'modal-button button-confirm';
    confirmBtn.textContent = opts.confirmText;
    confirmBtn.onclick = function() {
      opts.onConfirm(input.value);
      resolve(input.value);
      document.body.removeChild(modal);
    };
    
    // 添加取消按钮
    const cancelBtn = document.createElement('button');
    cancelBtn.className = 'modal-button button-cancel';
    cancelBtn.textContent = opts.cancelText;
    cancelBtn.onclick = function() {
      opts.onCancel();
      resolve(null);
      document.body.removeChild(modal);
    };
    
    // 组装元素
    body.appendChild(message);
    body.appendChild(input);
    
    footer.appendChild(cancelBtn);
    footer.appendChild(confirmBtn);
    
    content.appendChild(header);
    content.appendChild(body);
    content.appendChild(footer);
    modal.appendChild(content);
    
    // 添加到页面
    document.body.appendChild(modal);
    
    // 自动聚焦输入框
    input.focus();
    
    // 点击外部不关闭(保留原生 prompt 的行为)
    // 如果需要点击外部关闭,可以添加以下代码:
    /*
    modal.addEventListener('click', function(e) {
      if (e.target === modal) {
        resolve(null);
        document.body.removeChild(modal);
      }
    });
    */
    
    // 支持按 Enter 键提交
    input.addEventListener('keydown', function(e) {
      if (e.key === 'Enter') {
        confirmBtn.click();
      }
      if (e.key === 'Escape') {
        cancelBtn.click();
      }
    });
  });
}

// 使用示例
async function promptAction() {
  const name = await customPrompt({
    title: '用户信息',
    message: '请输入你的姓名:',
    placeholder: '例如:张三',
    defaultValue: '游客'
  });
  
  if (name !== null) {
    alert(`欢迎,${name || '未命名用户'}!`);
  } else {
    alert('操作已取消');
  }
}
</script>

</body>
</html>

四、三种方式的对比

特性

原生 Prompt

自定义 Prompt

Promise 版本

样式控制

无法自定义

完全自定义

完全自定义

页面阻塞

功能扩展性

基础文本输入

支持各种输入类型、验证

支持各种输入类型、验证

调用方式

同步

回调函数

Promise/async-await

兼容性

所有浏览器都支持

需要确保 CSS/JS 兼容性

现代浏览器

五、实际应用建议

  1. 简单需求:使用原生 prompt(),如快速获取用户输入。
  2. 复杂交互:使用自定义弹窗,如需要定制样式、添加验证逻辑或支持不同类型的输入。
  3. 现代项目:推荐使用基于 Promise 的版本,代码更简洁,支持 async/await 语法。

六、弹窗使用最佳实践

  1. 避免过度使用:使用原生 alert(),例如调试或临时提示。
  2. 提供明确的操作:确保用户知道如何关闭或响应弹窗。
  3. 使用自定义样式:原生弹窗样式固定,自定义模态框可提供更好的用户体验。
  4. 避免阻塞UI:原生弹窗会阻塞页面操作,考虑使用非阻塞的替代方案。
  5. 不要隐藏关闭按钮:确保用户随时可以关闭弹窗。
  6. 不要过度设计:弹窗内容应简洁明了,避免复杂的布局。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表