jquery addClass没有按正确的顺序应用

时间:2016-09-15 12:46:46

标签: javascript jquery addclass

在下面的示例中,我会在点击时立即向正文添加一个类busy。这应该将背景变为红色。然后我在每个循环完成后删除这个类。

实际上发生的事情是,在循环完成后添加类busy,然后立即删除。我知道情况就是这样,因为如果我删除循环中的removeClass条件,则添加类busy并保持添加。我无法理解为什么。我已经被困在这个问题上超过一个小时了,我已经完全停顿了。

在小提琴示例中,单击列3。

小提琴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');
  });
}

2 个答案:

答案 0 :(得分:1)

您的代码永远不会返回浏览器,以允许它在启动工作和删除类之前显示添加类导致的更新状态。您的主要JavaScript代码运行在一个也用于更新UI的线程上(由于多种原因,这很重要)。

如果要允许看到类的效果,请使用持续时间为0或非常小的数字的setTimeout返回浏览器(使用目标浏览器进行测试,我不得不使用有时在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放在答案中)。

答案 1 :(得分:0)

强制重绘的所有更改仅在当前功能完成后才会应用。由于您的点击处理程序都会添加然后删除.busy标记,因此无法完成更改。进行排序调用&#39; async&#39;将解决此问题。

$(".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");
});