文本框改变时进行Ajax调用,但不是每次都调用

4
我正在为我的Laravel应用程序的用户创建一种笔记系统。我希望在用户完成输入后保存他们的笔记文本区域,而不是在每次更改时运行ajax调用,因为那会产生大量请求。
最好的方法是什么?我应该在这里使用某种定时器来确定用户是否已经完成输入吗?
目前我只是使用以下内容:
notesTextarea.on('change', function(e) {
   $.ajax({ ... });
});
5个回答

3
您可以使用 onblur 事件代替。当元素失去焦点时会触发此事件,这意味着您不再更改它的内容:

$("#notesTextarea").on('blur', function(e) {
     // $.ajax({ ... });
     console.log("has finished, content to be saved:" + $(this).val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
Notes: <textarea id="notesTextarea"></textarea>
</p>
<p>
Other something: <input type="text">
</p>


3

在按下 keydown 事件的同时,您可以通过以下方式来调用回车键:

notesTextarea.on('keydown', function(e) {
  if(e.keyCode == 13){
    $.ajax({ ... });
  }
});

您还可以考虑blur事件,在元素失去焦点时会触发该事件。

notesTextarea.on('blur', function(e) {
  $.ajax({ ... }); 
});

1
不知道为什么我觉得这很难...谢谢! - Kaizokupuffball
@Kaizokupuffball,非常欢迎你。有时候我们只需要另一双眼睛:) - Mamun

3
虽然其他提出的解决方案(在失去焦点或按下回车键时)可以起作用,但我认为这并不是你要寻找的。如果用户既不单击文本区域外,也不使用回车键,那该怎么办呢?我会使用一种叫做“防抖”的技术。您可以在此处阅读有关它的信息:https://davidwalsh.name/javascript-debounce-function 或在此处查看示例:https://www.geeksforgeeks.org/debouncing-in-javascript/
简而言之,它仅在事件停止触发一段时间后才调用函数。
通过使用NPM包(例如https://www.npmjs.com/package/debounce)将防抖功能添加到您的代码中,或直接添加所需的代码。
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

来源:https://davidwalsh.name/javascript-debounce-function,该文章引自Underscore.js

然后编写一个函数来执行您的 ajax 调用:

var makeAjaxCall = function(e) {
    $.ajax({ ... });
};

现在你可以像这样简单地添加一个监听器:
var minTimeoutBetweenCallsInMilliSeconds = 500;
notesTextarea.on('change', debounce(makeAjaxCall, minTimeoutBetweenCallsInMilliSeconds));

现在,makeAjaxCall函数将只在最后一个更改事件发生500毫秒后被调用,即用户停止输入。


1
看起来这是更好的解决方案,因为它不是在按回车键时触发(因为笔记中可能存在回车键)。谢谢! - Kaizokupuffball

0

类似于 @Mamun 的回答。

keypress 事件上调用 Ajax:

$("textarea").on('keypress', function() {
    //$.ajax({ ... });
    console.log('request sent!');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>
<textarea id="textarea"></textarea>
</p>


0
如果您想自动保存,可以在用户输入N个字符后每次调用ajax。
否则,您可以在按下CTRL+S键组合时调用ajax函数。
document.addEventListener('keydown', function(event) {

if (event.ctrlKey && event.key == 's') {
event.preventDefault();  //prevent default file save box open by browser
  alert('ajax call goes here!');


}

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接