SweetAlert2技术问题:如何添加第二个弹窗而不替换第一个
嘿,这个问题我之前也碰到过!SweetAlert2本身是单例设计的,同一时间只能存在一个弹窗实例,所以你调用第二个弹窗时会直接替换掉第一个。不过有两种靠谱的解决思路,看你更倾向哪种:
方案一:关闭新弹窗后恢复原表格弹窗
这个思路是先关闭原弹窗,打开新的输入弹窗,等用户处理完输入后,再重新渲染原表格弹窗(还能顺便更新表格数据)。代码示例如下:
// 先定义原表格弹窗的完整配置,方便后续复用 const originalTableSwal = { title: '数据列表', html: ` <table style="border-collapse: collapse; width: 100%;"> <thead> <tr><th style="border:1px solid #ddd; padding:8px;">ID</th><th style="border:1px solid #ddd; padding:8px;">内容</th><th style="border:1px solid #ddd; padding:8px;">操作</th></tr> </thead> <tbody> <tr><td style="border:1px solid #ddd; padding:8px;">1</td><td style="border:1px solid #ddd; padding:8px;">测试数据1</td><td style="border:1px solid #ddd; padding:8px;"><button id="editBtn1" style="padding:4px 8px;">编辑</button></td></tr> <tr><td style="border:1px solid #ddd; padding:8px;">2</td><td style="border:1px solid #ddd; padding:8px;">测试数据2</td><td style="border:1px solid #ddd; padding:8px;"><button id="editBtn2" style="padding:4px 8px;">编辑</button></td></tr> </tbody> </table> `, showConfirmButton: false }; // 初始化打开表格弹窗 Swal.fire(originalTableSwal); // 给按钮绑定点击事件(这里用事件委托更稳妥,避免重新渲染后事件失效) document.addEventListener('click', async (e) => { if (e.target.id.startsWith('editBtn')) { // 获取当前行的ID,方便后续处理 const rowId = e.target.id.replace('editBtn', ''); // 关闭原表格弹窗 await Swal.close(); // 打开输入弹窗 const inputResult = await Swal.fire({ title: `编辑ID ${rowId} 的内容`, input: 'text', inputPlaceholder: '输入新内容', showCancelButton: true, confirmButtonText: '保存' }); // 处理用户输入结果 if (inputResult.isConfirmed) { // 这里可以更新原表格的内容,比如替换对应行的文本 originalTableSwal.html = originalTableSwal.html.replace( `测试数据${rowId}`, inputResult.value ); console.log(`已更新ID ${rowId} 的内容为: ${inputResult.value}`); } // 重新打开表格弹窗 Swal.fire(originalTableSwal); } });
这种方案逻辑简单,不需要额外写样式,唯一的小缺点是弹窗切换时会有轻微的闪烁感,但大部分场景下用户不会在意。
方案二:在原弹窗内嵌套自定义子弹窗
如果你想要完全避免弹窗切换的闪烁,可以在原SweetAlert2弹窗的HTML内容里,嵌入一个自定义的模态框(默认隐藏),点击按钮时显示这个子弹窗,本质上还是同一个SweetAlert2实例,不会被替换。代码示例:
Swal.fire({ title: '数据列表', html: ` <table style="border-collapse: collapse; width: 100%; margin-bottom:20px;"> <thead> <tr><th style="border:1px solid #ddd; padding:8px;">ID</th><th style="border:1px solid #ddd; padding:8px;">内容</th><th style="border:1px solid #ddd; padding:8px;">操作</th></tr> </thead> <tbody> <tr><td style="border:1px solid #ddd; padding:8px;">1</td><td style="border:1px solid #ddd; padding:8px;">测试数据1</td><td style="border:1px solid #ddd; padding:8px;"><button onclick="openEditModal(1)" style="padding:4px 8px;">编辑</button></td></tr> <tr><td style="border:1px solid #ddd; padding:8px;">2</td><td style="border:1px solid #ddd; padding:8px;">测试数据2</td><td style="border:1px solid #ddd; padding:8px;"><button onclick="openEditModal(2)" style="padding:4px 8px;">编辑</button></td></tr> </tbody> </table> <!-- 自定义子弹窗,默认隐藏 --> <div id="editModal" style="display:none; position:fixed; top:50%; left:50%; transform:translate(-50%,-50%); background:#fff; padding:24px; border-radius:8px; z-index:10000; box-shadow:0 4px 12px rgba(0,0,0,0.15); width:320px;"> <h3 style="margin-top:0; margin-bottom:16px;">编辑内容</h3> <input type="text" id="modalInput" style="width:100%; padding:8px; margin-bottom:16px; border:1px solid #ddd; border-radius:4px;"> <div style="display:flex; gap:8px; justify-content:flex-end;"> <button onclick="closeEditModal()" style="padding:6px 12px; border:none; border-radius:4px; background:#eee; cursor:pointer;">取消</button> <button onclick="confirmEdit()" style="padding:6px 12px; border:none; border-radius:4px; background:#007bff; color:#fff; cursor:pointer;">保存</button> </div> </div> <!-- 遮罩层,增强模态感 --> <div id="modalOverlay" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); z-index:9999;"></div> `, showConfirmButton: false, // 确保遮罩层能覆盖背景 customClass: { container: 'swal2-container--nested' } }); // 存储当前编辑的行ID let currentEditId = null; function openEditModal(rowId) { currentEditId = rowId; // 可以预先填充当前行的内容到输入框 document.getElementById('modalInput').value = `测试数据${rowId}`; // 显示子弹窗和遮罩层 document.getElementById('editModal').style.display = 'block'; document.getElementById('modalOverlay').style.display = 'block'; } function closeEditModal() { document.getElementById('editModal').style.display = 'none'; document.getElementById('modalOverlay').style.display = 'none'; currentEditId = null; } function confirmEdit() { const inputValue = document.getElementById('modalInput').value; if (!inputValue) return; // 更新表格中对应行的内容 const rows = document.querySelectorAll('.swal2-content table tbody tr'); rows[currentEditId - 1].querySelector('td:nth-child(2)').textContent = inputValue; console.log(`已更新ID ${currentEditId} 的内容为: ${inputValue}`); closeEditModal(); }
这种方案没有弹窗切换的闪烁,体验更流畅,但需要自己写子弹窗的样式和逻辑,好处是可以完全自定义子弹窗的外观,和原SweetAlert2风格保持一致也很容易。
内容的提问来源于stack exchange,提问作者Kevin Garduño
相关产品推荐
相关产品推荐

