我有一个表格列表,每行都有一个'notes'字段。我希望能够使用ajax更新它们并在更新后显示一条消息,但我很难找出正确的代码。
我的计划是捕获按键,然后将音符ID传递给计时器,每次用户按下按键时都会重置该计时器,这样只有在他们停止输入1秒后才会运行。问题是,如果页面上有多个注释,我需要将它传递给一个数组并在每个数组上重置计时器,如果可能的话?
这是我的代码:
var waitTime = 1000;
var click = false;
var timers = new Array();
$('.notes').keyup(function(){
var timerVariable = $(this).attr('id').split("-");
timerVariable = timerVariable[0];
timerVariable = timerVariable.replace('note', '');
timers.push(timerVariable);
timers[timerVariable] = timerVariable;
if(click==false){
var id = $(this).attr('id');
if(click==false){
click= true;
timerVariable = setTimeout(function(){doneTyping(id)}, waitTime);
}
}
});
$('.notes').keydown(function(){
for (var timer in timers) {
clearTimeout(timer);
}
click = false;
});
function doneTyping (id) {
var staffNo = id.split("-");
staffNo = staffNo[0];
staffNo = staffNo.replace('note', '');
var data = 'data='+id+'¬e='+$('#'+id).val();
$.ajax({
url: "update-notes.php",
type: "GET",
data: data,
cache: false,
success: function (html) {
jGrowlTheme('mono', 'Updated ' + staffNo, 'Thank you, the note has been updated.', 'tick.png');
}
});
}
我想知道问题是否可能与我调用for循环或其他方式有关?非常欢迎任何建议,谢谢!
答案 0 :(得分:4)
我就是这样做的:
var t;
$(document).ready(function() {
$('#search_string').keyup(function() {
clearTimeout (t);
t = setTimeout('start_ajax()', 3000);
});
});
start_ajax() {
// Do AJAX.
}
答案 1 :(得分:1)
这不是你问题的直接答案,但我会亲自从你的代码中创建一个jquery插件,你可以这样使用:
$('.note-fields').myNoteAjaxPlugin({ waitFor: '1000' });
每个“注释字段”都有它的插件实例,封装了专用于每个字段的计时器。无需担心存储在数组等中。
有很多插件模式和样板,例如 this one 和 this other one 。
以下是一个示例实现。我使用了一个样板并将其与jquery ui桥代码(它检查私有方法,重新使用以前的插件实例或正确实例化)合并:
;(function ( $, window, document, undefined ) {
// Create the defaults once
var pluginName = 'myNoteAjaxPlugin',
defaults = {
waitFor: "1000",
};
// The actual plugin constructor
function Plugin( element, options ) {
this.element = element;
this.$element = $(element);
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this._name = pluginName;
this._timer = null;
this._click = false;
this._init();
}
Plugin.prototype._init = function () {
var self = this;
this.$element.keyup(function(e){
if( self._click === false ){
var id = self.element.id;
if( self._click === false ){
self._click = true;
self._timer = setTimeout(function(){self._doneTyping(id)}, self.options.waitFor);
}
}
});
this.$element.keydown(function(e) {
if (self._timer) {
clearTimeout(self._timer);
}
self._click = false;
});
};
Plugin.prototype._doneTyping = function(id) {
alert('done typing');
};
$.fn[pluginName] = function( options ) {
var isMethodCall = typeof options === "string",
args = Array.prototype.slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.extend.apply( null, [ true, options ].concat(args) ) :
options;
// prevent calls to internal methods
if ( isMethodCall && options.charAt( 0 ) === "_" ) {
return returnValue;
}
if ( isMethodCall ) {
this.each(function() {
var instance = $.data( this, pluginName ),
methodValue = instance && $.isFunction( instance[options] ) ?
instance[ options ].apply( instance, args ) :
instance;
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue;
return false;
}
});
} else {
this.each(function() {
var instance = $.data( this, pluginName );
if ( instance ) {
instance.option( options || {} )._init();
} else {
$.data( this, pluginName , new Plugin( this , options) );
}
});
}
return returnValue;
};
})( jQuery, window, document );
$('#myinput').myNoteAjaxPlugin({waitFor: '1500'});
工作DEMO
答案 2 :(得分:1)
问题可能出在这部分代码中:
$('.notes').keyup(function(){
var timerVariable = $(this).attr('id').split("-");
timerVariable = timerVariable[0];
timerVariable = timerVariable.replace('note', '');
timers.push(timerVariable);
timers[timerVariable] = timerVariable;
if(click==false){
var id = $(this).attr('id');
if(click==false){
click= true;
timerVariable = setTimeout(function(){doneTyping(id)}, waitTime);
}
}
});
我不确定你为什么timers.push(timerVariable);
紧随其后timers[timerVariable] = timerVariable;
- 他们都将timerVariable
添加到数组中,只是在(可能?)不同的位置。< / p>
此外,虽然我知道Javascript允许它,但我仍然认为改变变量的类型是不好的做法。保留timerVariable
作为数组的索引,并在调用setTimeout
时创建一个新变量,而不是重用timerVariable
。它使您的代码更容易理解,并减少引入错误的可能性。
最后,请致电setTimeout
然后添加到您的阵列。您的代码没有按照您的想法执行 - 您实际上从未将setTimeout
调用创建的引用添加到数组中。看看this jsFiddle,看看实际发生了什么。
答案 3 :(得分:1)
考虑更精简的代码版本:
$('.notes')
.each(function () {
$(this).data("serverState", {busy: false, date: new Date(), val: $(this).val() });
})
.bind("keyup cut paste", function() {
var note = this, $note = $(this), serverState = $note.data("serverState");
setTimeout(function () {
var val = $note.val();
if (
!serverState.busy
&& new Date() - serverState.date > 1000 && val != serverState.val
) {
$.ajax({
url: "update-notes.php",
type: "POST",
data: { data: note.id, note: val },
cache: false,
success: function (html) {
var staffNo = note.id.split("-")[0].replace('note', '');
serverState.date = new Date();
serverState.val = val;
jGrowlTheme('mono', 'Updated ' + staffNo, 'Thank you, the note has been updated.', 'tick.png');
},
error: function () {
// handle update errors
},
complete: function () {
serverState.busy = false;
}
});
}
}, 1000);
});
<input>
的当前状态将保存为serverState
缓存中的.data()
。serverState.busy
),如果有请求则退出(不需要通过请求锤击服务器)。serverState
设置为新值,而不是错误。为自己实现错误处理。因此,每次按键都会触发该功能,但在最后一次按键后实际更改值更改的1000ms被推送到服务器。