jquery addClass 的应用顺序不正确
jquery addClass isn't being applied in the right order
在下面的示例中,我在单击时立即向正文添加 class busy
。这应该将背景变成红色。然后我在每个循环完成后删除这个 class。
实际上发生的是 class busy
在循环完成后被添加,然后立即被删除。我知道是这种情况,因为如果我在循环中删除 removeClass
条件,则会添加 class busy
并保持 added.I 不明白为什么。我在这个问题上被困了一个多小时,现在完全停滞不前。
在 fiddle 示例中,单击第 3 列。
Fiddle https://jsfiddle.net/2nvopbqo/3/
$(".sort").click(function() {
$('body').addClass('busy');
var col = $(this).parent().children().index($(this));
var desc = $(this).hasClass('desc');
var date = $(this).hasClass('date');
sortTable(desc, col, date);
$(this).toggleClass("desc asc");
});
function sortTable(order, col, date) {
var rows = $('#mytable tbody tr').get();
rows.sort(function(a, b) {
var A = $(a).children('td').eq(col).text().toUpperCase();
var B = $(b).children('td').eq(col).text().toUpperCase();
if (date) {
var A = A.split("-").reverse().join('-');
var B = B.split("-").reverse().join('-');
}
if (order) {
if (B < A) return -1;
if (B > A) return 1;
} else {
if (A < B) return -1;
if (A > B) return 1;
}
return 0;
});
var totalRows = rows.length;
$.each(rows, function(index, row) {
$('#mytable').children('tbody').append(row);
if (index == totalRows - 1) $('body').removeClass('busy');
});
}
您的代码永远不会返回给浏览器以允许它显示在启动工作和删除 class 之前添加 class 导致的更新状态。您的主要 JavaScript 代码在一个线程上运行,该线程也用于更新 UI(这很重要,原因有几个)。
如果你想让 class 的效果被看到,用 setTimeout
返回给浏览器,持续时间为 0 或一个非常小的数字(用你的目标测试浏览器,有时我不得不在 Firefox 上使用 ~40ms):
$(".sort").click(function() {
$('body').addClass('busy');
var $this = $(this);
setTimeout(function() {
var col = $this.parent().children().index($(this));
var desc = $this.hasClass('desc');
var date = $this.hasClass('date');
sortTable(desc, col, date);
$this.toggleClass("desc asc");
}, 40);
});
Updated Fiddle(因为我无法将所有这些 HTML 放在一个答案中)。
所有强制重绘的更改仅在当前功能完成后应用。由于您的点击处理程序既添加又删除 .busy
标记,因此更改未完成。进行排序调用 'async' 将解决此问题。
$(".sort").click(function() {
$('body').addClass('busy');
var col = $(this).parent().children().index($(this));
var desc = $(this).hasClass('desc');
var date = $(this).hasClass('date');
//will fire after the click handler is done.
setTimeout(sortTable,0,desc, col, date);
// you could also use requestAnimationFrame
$(this).toggleClass("desc asc");
});
在下面的示例中,我在单击时立即向正文添加 class busy
。这应该将背景变成红色。然后我在每个循环完成后删除这个 class。
实际上发生的是 class busy
在循环完成后被添加,然后立即被删除。我知道是这种情况,因为如果我在循环中删除 removeClass
条件,则会添加 class busy
并保持 added.I 不明白为什么。我在这个问题上被困了一个多小时,现在完全停滞不前。
在 fiddle 示例中,单击第 3 列。
Fiddle https://jsfiddle.net/2nvopbqo/3/
$(".sort").click(function() {
$('body').addClass('busy');
var col = $(this).parent().children().index($(this));
var desc = $(this).hasClass('desc');
var date = $(this).hasClass('date');
sortTable(desc, col, date);
$(this).toggleClass("desc asc");
});
function sortTable(order, col, date) {
var rows = $('#mytable tbody tr').get();
rows.sort(function(a, b) {
var A = $(a).children('td').eq(col).text().toUpperCase();
var B = $(b).children('td').eq(col).text().toUpperCase();
if (date) {
var A = A.split("-").reverse().join('-');
var B = B.split("-").reverse().join('-');
}
if (order) {
if (B < A) return -1;
if (B > A) return 1;
} else {
if (A < B) return -1;
if (A > B) return 1;
}
return 0;
});
var totalRows = rows.length;
$.each(rows, function(index, row) {
$('#mytable').children('tbody').append(row);
if (index == totalRows - 1) $('body').removeClass('busy');
});
}
您的代码永远不会返回给浏览器以允许它显示在启动工作和删除 class 之前添加 class 导致的更新状态。您的主要 JavaScript 代码在一个线程上运行,该线程也用于更新 UI(这很重要,原因有几个)。
如果你想让 class 的效果被看到,用 setTimeout
返回给浏览器,持续时间为 0 或一个非常小的数字(用你的目标测试浏览器,有时我不得不在 Firefox 上使用 ~40ms):
$(".sort").click(function() {
$('body').addClass('busy');
var $this = $(this);
setTimeout(function() {
var col = $this.parent().children().index($(this));
var desc = $this.hasClass('desc');
var date = $this.hasClass('date');
sortTable(desc, col, date);
$this.toggleClass("desc asc");
}, 40);
});
Updated Fiddle(因为我无法将所有这些 HTML 放在一个答案中)。
所有强制重绘的更改仅在当前功能完成后应用。由于您的点击处理程序既添加又删除 .busy
标记,因此更改未完成。进行排序调用 'async' 将解决此问题。
$(".sort").click(function() {
$('body').addClass('busy');
var col = $(this).parent().children().index($(this));
var desc = $(this).hasClass('desc');
var date = $(this).hasClass('date');
//will fire after the click handler is done.
setTimeout(sortTable,0,desc, col, date);
// you could also use requestAnimationFrame
$(this).toggleClass("desc asc");
});