是否有 jquery 事件在焦点离开元素之前或下一个元素获得焦点之前运行?

Is there a jquery event the runs just before focus leaves an element or just before the next element gains focus?

我有一个表单,其中有两个输入元素有些交织在一起。在元素#1(元素#2 在 tabindex 顺序中元素#1 之后),一旦用户试图离开该字段,我 运行 一个 ajax 调用来检查输入的值是否已经存在在数据库中,如果是,请使用 javascript 确认对话框向用户提问。第二个元素在获得焦点后会自动弹出一个模式 window,其中包含用户可以做出的选择。我正在使用 Jquery.

我想 运行 在用户离开第一个元素时立即调用“此数据是否存在”ajax。 Blur 事件似乎正是我想要的,因为无论用户是否进行了更改,都需要检查现有数据。

不过,我使用模糊的问题是它的处理程序 运行s 在第一个元素失去焦点并且焦点跳转到元素 #2 之后。因此,元素 #1 的模糊处理程序会在元素 #2 的焦点处理程序弹出选择模式的同时弹出确认屏幕,我现在同时打开了 2 个弹出窗口。

我想让用户有机会在弹出元素 #2 的选项之前回答确认提示中的问题。

是否有类似于模糊的 Jquery 事件,但 运行 就在焦点实际丢失之前?或者,有没有办法阻止下一个元素获得焦点,直到第一个元素的模糊处理程序完成?

尝试在模糊处理程序中停止传播或 preventDefault() 不会执行任何操作,因为在模糊处理程序 运行s 之前已经发生了对元素 #2 的关注。

我试过将元素#2 的 tabindex 设置为 -1,然后在需要时以编程方式关注该元素,但是远离该元素的 Tab 键成为一个问题,反向 Tab 键会跳过它(直接跳转到元素# 1) - 我仍然希望该元素在 tabindex 排序中,但只是不希望它获得焦点,直到元素#1 完成其失去焦点时需要 运行 的处理程序。

我也尝试过设置状态变量,但是当我添加代码来处理两个元素之间的转换时,我最终遇到了类似的问题,并且它带来了额外的边缘情况复杂性。我也试过弄乱 mousedown 和 keydown 事件并试图阻止默认处理,但这也增加了显着的复杂性和错误空间。

欢迎提出任何想法。谢谢。

此解决方案有点乱七八糟,但可以实现您的目标。诀窍是放置相当于接受模糊焦点的“无操作”元素。然后控制 AJAX 请求后的选项卡。

在每次“模糊”事件时,我们都会进行测试以确保捕获正确的 <input> 元素(我会将这些细节留给您)。

AJAX请求完成后,再关注下一个<input>

对于此演示,在第二个输入中键入 2,然后 tab。我添加了一个短暂的延迟,所以你可以看到它有效。

$("input").on('blur', function(e){
  if(this.value == 2) {
    console.log("do ajax request");
    setTimeout((function(){
      $(this).next().next('input').focus();
    }).bind(this), 500);
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input tabindex="1" />
<input tabindex="2" />
<div tabindex="3"></div>
<input tabindex="3" />

这样的事情会成功吗?

有一个变量来指示是否可以显示第二个弹出窗口

let allowSecondPopup = true;

有一个变量指示显示第二个弹出窗口是否被推迟

let secondPopupPostponed = false;

当第一个输入获得焦点时设置变量

$("#input1").on("focus", fuction () {
    allowSecondPopup = false;
});

在 blur

上发送 ajax
$("#input1").on("blur", function () {
    //$("#input1").disabled(true);
    //$("#input2").disabled(true);
    $.post("https://example.com", { }, fuction (response) {
        if (secondPopupPostponed) {
            // Only show second popup after the ajax-call has finished
            showSecondPopup();
            allowSecondPopup = true;
            secondPopupPostponed = false;
        }
    });
});

并且当第二个输入获得焦点时,检查变量

$("#input2").on("focus", fuction () {
    if (allowSecondPopup) {
        showSecondPopup();
    } else {
        // We're still waiting for the ajax-call to complete. 
        // When the ajax-call completes, the callback will show the second popup.
        secondPopupPostponed = true;
    }
});