jQuery中confirm弹窗循环弹出问题的原因及解决方法
问题原因分析
- 取消操作触发重复blur循环:在
blur事件处理函数中调用textarea.focus()时,弹窗关闭后textarea会强制获得焦点,但此时用户鼠标大概率已经点击了页面其他区域,导致textarea再次失去焦点,重新触发blur事件,进而重复弹出确认窗口。 - 确定操作的异步延迟问题:如果
update方法是异步AJAX请求,在请求完成、页面刷新前,弹窗关闭后焦点会转移到其他元素,同样会再次触发textarea的blur事件,导致弹窗重复出现。
修复方案
通过添加状态锁避免重复触发弹窗,同时调整焦点控制和异步逻辑的执行时机:
// 状态锁:标记是否正在处理确认弹窗,防止重复触发 let isConfirming = false; let originalValue = ''; // 监听下拉框变化,保存textarea初始值 document.getElementById('betreffDropdown').addEventListener('change', function() { originalValue = document.getElementById('nachrichtentext').value; }); // 监听textarea失去焦点事件 document.getElementById('nachrichtentext').addEventListener('blur', function(e) { const textarea = e.target; // 已在弹窗流程中,直接跳过 if (isConfirming) return; // 内容未修改,无需处理 if (textarea.value === originalValue) return; isConfirming = true; const needSave = confirm('内容已修改,是否保存?'); if (needSave) { // 点击确定:执行更新后刷新页面 update().then(() => { window.location.reload(); }).catch(() => { // 请求失败时释放锁,恢复正常交互 isConfirming = false; }); } else { // 点击取消:恢复焦点,并在焦点真正获取后释放锁 textarea.focus(); // 只执行一次的焦点监听,避免重复触发blur textarea.addEventListener('focus', function unlock() { isConfirming = false; textarea.removeEventListener('focus', unlock); }, { once: true }); } }); // 模拟异步更新方法(替换为你的AJAX逻辑) function update() { return new Promise((resolve) => { setTimeout(() => { // 此处执行AJAX更新逻辑 resolve(); }, 800); }); }
关键修复点说明
- 状态锁
isConfirming:确保同一时间只有一个确认弹窗在处理,彻底避免重复触发。 - 取消操作的焦点控制:通过一次性
focus事件监听,确保textarea真正获得焦点后再释放锁,避免立即触发新的blur。 - 异步更新的流程控制:在AJAX请求完成后再刷新页面,同时捕获错误释放锁,防止锁一直处于激活状态。
内容的提问来源于stack exchange,提问作者citr0q
相关产品推荐
相关产品推荐

