我正在研究一些jQuery,以检查表中的单元格是否已被编辑。如果有,则修订通过ajax发送回数据库。我正在使用超时延迟为用户提供2500毫秒的击键次数以进行全面校正并在完成时捕获。如果他们点击html表中的其他td
,我也会使用模糊绕过超时延迟。一旦ajax完成,我添加一个"已保存的" class td
并在if
语句中包含ajax,这样只有在"保存"时才会出现ajax。上课没有。这只允许ajax发生一次。
我的问题:如果更改了某个号码并立即点击了其他td
并且用户开始输入,则之前的更改永远不会将其设置为ajax,因此它永远不会保存到数据库。 1毫秒计时器使得看起来似乎没有可能发生这种情况,但某些事情必然会以某种方式减慢它。
我的问题:为什么会发生这种情况,我该如何解决?
旁注: toastr代码也停止了工作,我不确定原因。
$('td').on('input blur', function(e) {
var timeoutDelay=2500;
if( e.type == "blur"){
timeoutDelay=1;
}
// If NOT already saved...
if( !$(this).hasClass("saved") ){
var _this = $(this); // preserve reference to the input field here
clearTimeout(saveTimeout);
saveTimeout = setTimeout(function() {
console.log(_this)
$.ajax({
method: "POST",
url: "updatedatabase.php",
data: {
content: _this.text(),
date: _this.siblings().first().text(),
prod: $('tr:first-child th:nth-child(' + (_this.index() + 1) + ')').text(),
old: old
}
})
.done(function( msg ) {
alert( msg );
// Add the "saved" class to prevent other saving
_this.addClass("saved");
});
toastr.options = {
"positionClass": "toast-top-center",
"onclick": null,
"timeOut": "2500",
}
toastr.info(old,'Database Updated!<br><br>Your Previous Amount Was:');
_this.prop('contenteditable', false);
}, timeoutDelay);
}
});
$(document).ready(function () {
var old;
$('td').click(function(){
old=$(this).text();
$(this).prop('contenteditable', true);
});
var saveTimeout;
// Remove the "saved" class on keydown
$('td').on('keydown', function(e) {
$(this).removeClass("saved");
});
$('td').on('input blur', function(e) {
var timeoutDelay=2500;
if( e.type == "blur"){
timeoutDelay=1;
}
// If NOT already saved...
if( !$(this).hasClass("saved") ){
var _this = $(this); // preserve reference to the input field here
// Add the "saved" class to prevent other saving
_this.addClass("saved");
clearTimeout(saveTimeout);
saveTimeout = setTimeout(function() {
console.log(_this)
$.ajax({
method: "POST",
url: "updatedatabase.php",
data: {
content: _this.text(),
date: _this.siblings().first().text(),
prod: $('tr:first-child th:nth-child(' + (_this.index() + 1) + ')').text(),
old: old
}
})
.done(function( msg ) {
alert( msg );
});
toastr.options = {
"positionClass": "toast-top-center",
"onclick": null,
"timeOut": "2500",
}
toastr.info(old,'Database Updated!<br><br>Your Previous Amount Was:');
_this.prop('contenteditable', false);
}, timeoutDelay);
}
});
$("td").hover(function(){
$(this).addClass('highlight').siblings().first().addClass('highlight');
$('tr:eq(1) th:eq('+$(this).index()+')').addClass('highlight');
},function(){
$(this).removeClass("highlight").siblings().first().removeClass('highlight');
$('tr:eq(1) th:eq('+$(this).index()+')').removeClass('highlight');
});
});
&#13;
table,th, td {
border: 1px solid black;
border-collapse: collapse;
}
.highlight {
background-color:#E0E0E0;
color: blue;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/1.3.1/css/toastr.css" rel="stylesheet"/>
<script src="http://cdnjs.cloudflare.com/ajax/libs/toastr.js/1.3.1/js/toastr.js"></script>
<table>
<tr>
<th>Item #</th>
<th>1234567</th>
<th>7654321</th>
<th>5678945</th>
</tr>
<tr>
<th>Product</th>
<th><u>22 ounce Dark</u></th>
<th><u>12count 4oz Dark</u></th>
<th><u>24count 6oz TJ</u></th>
</tr>
<tr>
<th>2016-01-03</th>
<td>13587</td>
<td>2203</td>
<td>4111</td>
</tr>
<tr>
<th>2016-01-04</th>
<td>14111</td>
<td>3247</td>
<td>4332</td>
</tr>
<tr>
<th>2016-01-05</th>
<td>13212</td>
<td>3101</td>
<td>3911</td>
</tr>
<tr>
<th>2016-01-06</th>
<td>16335</td>
<td>3299</td>
<td>4001</td>
</tr>
<tr>
<th>2016-01-07</th>
<td>15421</td>
<td>3100</td>
<td>4078</td>
</tr>
</table>
&#13;
答案 0 :(得分:1)
每当调用$('td').on('input blur', function(e) {
事件处理程序时,都会清除超时引用saveTimeout
,并且永远不会调用先前的超时。解决方案是每个td
都有一个超时参考。
这里没有检查草稿
if ( _this.saveTimeout )
clearTimeout(_this.saveTimeout);
_this.saveTimeout = setTimeout(function { ........
等等。
<强> CORRECTED:强>
clearTimeout(_this.data('saveTimeout'));
_this.data('saveTimeout', setTimeout(function() {
console.log("Saving " + _this.text()) + "...";
...
}, timeoutDelay));
答案 1 :(得分:0)
以下是事件的顺序:
input
事件的第一个单元格中的用户类型。td
没有类saved
,因此if (!$(this).hasClass("saved"))
的分支被占用。saved
已添加到td
。saveTimeout
中。我们称之为超时,超时A。blur
事件。td
,因此不会执行分支,也不会设置新的超时。< / strong>唯一仍然有效的超时是超时A. saved
个事件。input
没有td
类,因此分支被占用。saved
中找到超时A并取消它。它设置新的超时以在第二个单元格中保存更改。好的,所以我使用了你的代码片段并对其进行了一些修改。您的代码段发出了错误,因为没有加载toastr,并且没有任何东西可以接收AJAX,而且这个代码段遭受同样的问题。但是,它可以用来说明解决方案。我做的是:
如果偶数为saveTimeout
,则即使存在blur
类,也会强制设置新超时。
超时在DOM元素本身上保存。我之前已经在其他环境中完成了这项工作,并且我已经在多个浏览器中进行了测试,并且工作正常。但是,您可能会定位我不使用的浏览器。如果此方法使您可以使用任何允许基于DOM元素检索已保存超时的方法替换它。您可以使用元素ID查看从id到timeout的映射,或者使用what-have-you。使用任何让你感到舒服的东西。
根据我所做的更改,我可以在日志中看到第一个单元格的保存请求被触发,第二个单元格的不同请求也会触发。
saved
$(document).ready(function () {
var old;
$('td').click(function(){
old=$(this).text();
$(this).prop('contenteditable', true);
});
// Remove the "saved" class on keydown
$('td').on('keydown', function(e) {
console.log("remove");
$(this).removeClass("saved");
});
$('td').on('input blur', function(e) {
var timeoutDelay=2500;
if( e.type == "blur"){
timeoutDelay=1;
}
// If NOT already saved... or if it is a blur
if( !$(this).hasClass("saved") || e.type === "blur" ){
var _this = $(this); // preserve reference to the input field here
// Add the "saved" class to prevent other saving
_this.addClass("saved");
console.log("setting new timeout");
if (this.saveTimeout) {
clearTimeout(this.saveTimeout);
this.saveTimeout = null;
}
this.saveTimeout = setTimeout(function() {
console.log("timeout", _this.text());
$.ajax({
method: "POST",
url: "updatedatabase.php",
data: {
content: _this.text(),
date: _this.siblings().first().text(),
prod: $('tr:first-child th:nth-child(' + (_this.index() + 1) + ')').text(),
old: old
}
})
.done(function( msg ) {
alert( msg );
});
toastr.options = {
"positionClass": "toast-top-center",
"onclick": null,
"timeOut": "2500",
}
toastr.info(old,'Database Updated!<br><br>Your Previous Amount Was:');
_this.prop('contenteditable', false);
}, timeoutDelay);
}
});
$("td").hover(function(){
$(this).addClass('highlight').siblings().first().addClass('highlight');
$('tr:eq(1) th:eq('+$(this).index()+')').addClass('highlight');
},function(){
$(this).removeClass("highlight").siblings().first().removeClass('highlight');
$('tr:eq(1) th:eq('+$(this).index()+')').removeClass('highlight');
});
});
table,th, td {
border: 1px solid black;
border-collapse: collapse;
}
.highlight {
background-color:#E0E0E0;
color: blue;
}