Jquery 键盘上的Ajax vs用户完成键入

Jquery 键盘上的Ajax vs用户完成键入,jquery,ajax,timer,Jquery,Ajax,Timer,我想知道这是否是我想要的: 我有一个表格,也是一个如下所示的表格: Exercise | Reps | Lbs | Kg ------------------------------------- Squat | 8 | 135 | 61.23 Squat | 8 | 225 | 102.06 Squat | 6 | 315 | 142.88 Squat | 2 | 405 | 183.

我想知道这是否是我想要的:

我有一个表格,也是一个如下所示的表格:

Exercise  |  Reps  |  Lbs  |   Kg
-------------------------------------
Squat     |    8   |  135  |  61.23
Squat     |    8   |  225  |  102.06
Squat     |    6   |  315  |  142.88
Squat     |    2   |  405  |  183.70
Squat     |    1   |  485  |  219.99
其中“Reps”、“Lbs”和“Kg”值均可由用户编辑

我遇到了这个问题。我不想在每个keyup事件上发送ajax请求,我也不希望有提交按钮。我已经实现了一个计时器,这样一旦用户停止输入2秒(或多长时间),它就会更新。但是,我遇到的问题是,我无法在不同的行之间分离此计时器。让我解释一下:

如果在我的上表中,如果我用135磅编辑顶行,它将1)立即适当地更新Kg&&2)启动倒计时

如果我在225lbs处开始编辑下一行,计时器将重新开始,这意味着第一行不会得到更新

潜在的解决方案是允许计时器重新开始每次新的编辑,但当它最终完成时,然后更新所有内容。但这似乎也是一种浪费,因为从技术上讲,我的数量或行数可能是无限的

我曾经考虑过在任何一个被更改的类中添加一个类,然后只更新那些类…但是,如果他们更新一个类,然后再更新回原来的状态…那么它也不需要更新


关于如何处理此问题,您有什么建议吗?

您可以执行以下操作:

  • 当输入值更改时,在键控(或粘贴)上设置计时器
  • 当输入失去焦点(并且焦点已经改变)时,立即进行ajax调用
  • 关键是正确地取消计时器,并在必要时中止ajax调用

    function clearTimerForInput($input) {
        var timerId = $input.data('timerId');
        if (timerId) {
            clearTimeout(timerId);
            $input.removeData('timerId')
        }
    }
    
    function updateServerForInput($input) {
        var jqXhr = $input.data('jqXhr');
    
        clearTimerForInput($input);
    
        // Abort an existing ajax call.
        // Note: The call still gets to the server,
        //       but its response will be ignored.
        if (jqXhr) {
            jqXhr.abort();
            $input.removeData('jqXhr');
        }
    
        // Update the current value.
        $input.data('currentValue', $input.val());
    
        // Make the ajax call.
        $input.data('jqXhr', $.ajax({
            // ...
        });
    }
    
    $('#myTable')
        .on('focus', ':input', function() {
            var $input = $this;
            $input.data('currentValue', $input.val());
        });
        .on('keyup paste', ':input', function() {
            var $input = $this;
    
            clearTimerForInput($input);
    
            // Note: Not all keyup events will change the value.
            if ($input.val() != $input.data('currentValue')) {
                $input.data('timerId', setTimeout(function() {
                    updateServerForInput($input);
                }, 2000);
            }
        });
        .on('blur', ':input', function() {
            var $input = $this;
            if ($input.val() != $input.data('currentValue')) {
                updateServerForInput($input)
            }
        });
    

    注意:您需要中止ajax调用的原因是(非常)罕见的情况,即第二个ajax调用在第一个ajax调用之前返回。如果不中止第一个ajax调用,则在处理响应时将使用无效值更新页面。

    可以执行以下操作:

  • 当输入值更改时,在键控(或粘贴)上设置计时器
  • 当输入失去焦点(并且焦点已经改变)时,立即进行ajax调用
  • 关键是正确地取消计时器,并在必要时中止ajax调用

    function clearTimerForInput($input) {
        var timerId = $input.data('timerId');
        if (timerId) {
            clearTimeout(timerId);
            $input.removeData('timerId')
        }
    }
    
    function updateServerForInput($input) {
        var jqXhr = $input.data('jqXhr');
    
        clearTimerForInput($input);
    
        // Abort an existing ajax call.
        // Note: The call still gets to the server,
        //       but its response will be ignored.
        if (jqXhr) {
            jqXhr.abort();
            $input.removeData('jqXhr');
        }
    
        // Update the current value.
        $input.data('currentValue', $input.val());
    
        // Make the ajax call.
        $input.data('jqXhr', $.ajax({
            // ...
        });
    }
    
    $('#myTable')
        .on('focus', ':input', function() {
            var $input = $this;
            $input.data('currentValue', $input.val());
        });
        .on('keyup paste', ':input', function() {
            var $input = $this;
    
            clearTimerForInput($input);
    
            // Note: Not all keyup events will change the value.
            if ($input.val() != $input.data('currentValue')) {
                $input.data('timerId', setTimeout(function() {
                    updateServerForInput($input);
                }, 2000);
            }
        });
        .on('blur', ':input', function() {
            var $input = $this;
            if ($input.val() != $input.data('currentValue')) {
                updateServerForInput($input)
            }
        });
    

    注意:您需要中止ajax调用的原因是(非常)罕见的情况,即第二个ajax调用在第一个ajax调用之前返回。如果不中止第一个ajax调用,则在处理响应时将使用无效值更新页面。

    我认为,我刚才想到的一个很好的潜在解决方案是,在输入焦点发生变化时运行ajax。这将允许用户输入他们想要的任意多或少,如果他们转到另一个输入…它将更新原始输入。不过我还是想听听其他的建议。两个都做怎么样?如果用户键入并暂停2秒钟,则进行ajax调用。如果焦点离开输入,则进行ajax调用并取消计时器。这样你一次最多只能有一个计时器。没错……两者都可以。如果他们等待几秒钟,然后不做任何更改就离开输入,则可能是对服务器的额外呼叫…但这可能是一个很好的解决方案。我对焦点更改的解决方案相当满意…如果您想回答这个问题,我将接受。您应该能够避免额外呼叫。查看我的答案,了解可能的解决方案。在我看来,我刚刚想到的一个很好的潜在解决方案是,在输入焦点发生变化时运行ajax。这将允许用户输入他们想要的任意多或少,如果他们转到另一个输入…它将更新原始输入。不过我还是想听听其他的建议。两个都做怎么样?如果用户键入并暂停2秒钟,则进行ajax调用。如果焦点离开输入,则进行ajax调用并取消计时器。这样你一次最多只能有一个计时器。没错……两者都可以。如果他们等待几秒钟,然后不做任何更改就离开输入,则可能是对服务器的额外呼叫…但这可能是一个很好的解决方案。我对焦点更改的解决方案相当满意…如果您想回答这个问题,我将接受。您应该能够避免额外呼叫。看看我的答案,找到一个可能的解决方案。好答案…我喜欢堕胎,这不是我会想到的。好答案…我喜欢堕胎,这不是我会想到的。