You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery中confirm弹窗循环弹出问题的原因及解决方法

问题原因分析
  1. 取消操作触发重复blur循环:在blur事件处理函数中调用textarea.focus()时,弹窗关闭后textarea会强制获得焦点,但此时用户鼠标大概率已经点击了页面其他区域,导致textarea再次失去焦点,重新触发blur事件,进而重复弹出确认窗口。
  2. 确定操作的异步延迟问题:如果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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:07:14