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

如何阻止.focusout()事件多次触发?附问题复现示例

解决focusout事件切换input时触发循环的问题

嘿,这个问题我之前也碰到过!本质原因是两个点:focusout的冒泡特性,加上alert弹窗会强制抢占焦点,打乱了正常的焦点切换流程。

问题到底出在哪?

当你从第一个input切换到第二个input时,实际的事件流程是这样的:

  1. 第一个input失去焦点,触发它的focusout事件,这个事件会冒泡到body上的监听器,于是alert弹出来。
  2. 但alert一出现就会立刻抢走页面的所有焦点——这时候第二个input还没来得及真正获取焦点,就因为alert的出现被迫失去焦点,于是又触发一次body上的focusout,alert再次弹出,直接形成死循环。

给你几个可行的解决方案:

方案1:改用不冒泡的blur事件

blur事件不会向上冒泡,只会在触发它的那个input元素上生效,这样就不会因为冒泡引发后续的连锁反应。修改后的代码很简单:

$('body').on('blur', 'input', function(){ alert('test'); });

jQuery的事件委托对blur是支持的,不用担心绑定失效的问题。

方案2:通过relatedTarget判断焦点去向

如果必须要用focusout(比如需要冒泡特性处理其他元素),可以利用事件对象的relatedTarget属性,判断失去焦点后,焦点是不是转移到了页面内的另一个input上。如果是,就跳过执行alert:

$('body').on('focusout', 'input', function(e){
  // 只有当焦点完全离开input元素(比如点空白、切标签页)时才触发
  if (!e.relatedTarget || !$(e.relatedTarget).is('input')) {
    alert('test');
  }
});

这个方案能精准控制触发时机,既保留focusout的特性,又避免循环。

方案3:换掉alert,用不抢焦点的提示方式

alert的强制焦点抢占是循环的直接导火索,如果换成console日志或者页面内的提示元素,自然就不会有这个问题了:

$('body').on('focusout', 'input', function(){
  console.log('test');
  // 或者用页面内的提示框:
  // $('.tip').text('输入框失去焦点啦').fadeIn().delay(2000).fadeOut();
});

总结

如果不需要冒泡特性,方案1最省心;如果要保留focusout的功能,方案2是最优解;如果只是测试用,方案3也能快速解决问题。

内容的提问来源于stack exchange,提问作者Pa3k.m

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:09:03