title: Tablesorter resorting in combination with setInterval and CSS3 animation
body: <p>I make an application for betting where I load new JSON data on every 3s and if it is necessary, add, delete or update some rows. I use jQuery tablesorter plugin for table sorting by a column. It's working great, but I have one specific case. If there is a result change, I add "highlight" CSS class so that row will pulse about 8 seconds in orange using CSS3 animation and after completing of animation, that class is removed. This works perfectly, but if I use tablesorter resort option, that animation starts again on every 3s and practically never ends, because it lasts longer than set interval (3s is less than 8s). So, if I put resort option to false, the problem with animation doesn't exist and it will be continuous until it's finished, but I would like to use resort option on every update. </p>
  
  <p>To better explain the situation, here is a JSFiddle <a href="https://jsfiddle.net/savicmi/h9gpqrwn/15/" rel="nofollow noreferrer">https://jsfiddle.net/savicmi/h9gpqrwn/15/</a> that demonstrates the problem. If it is added a row with Basketball in it, that row's background will pulse. It seems that tablesorter redraws table's body if it is resort = true, and probably it is the reason for starting CSS3 animation from the beginning instead of continuous duration up to the end of an animation. How can this be solved?</p>
  
  <pre><code>$(document).ready(function() { 
    $(".table-liveevents").tablesorter({ 
      sortList: [[1,0]],
      ignoreCase: true,
      textExtraction: {
        '.sorter-date' : function(node, table, cellIndex){ 
          var dat =   node.textContent.split(/\/|\s|\:/);
          var date = dat[1]+'/'+dat[0]+'/'+dat[2]+' '+dat[3]+':'+dat[4];
          return new Date(date).getTime();                        
        }
      },
      resort: true
    });
  
  var data = {
    "live_ev": [
      {
        "id": 206622,
        "date": "28/06/2017 11:55",
        "name": "Evtimova, Dia - Dulgheru, Alexandra",
        "sport": "Tennis"
      },
      {
        "id": 206553,
        "date": "28/06/2017 11:40",
        "name": "Sabanin, Yan - Matsukevitch, Denis",
        "sport": "Tennis",
      },
      {
        "id": 206754,
        "date": "28/06/2017 13:05",
        "name": "Crvena Zvezda - Partizan",
        "sport": "Basketball"
      }]
  };
  
      function addRow(data, table) {
  
      if (table.find('tr#r_'+data.id).length == 0) {
          var tr = document.createElement('tr');      
          tr.id = 'r_' + data.id;
          tr.className = 'details';
          for(var j = 1; j &lt;= 3; j++){
            var td = document.createElement('td');
            td.appendChild(document.createTextNode( data[Object.keys(data)[j]]));
            tr.appendChild(td);
          }       
          table.find('tbody').append(tr); 
      }
      }
  
    var isFirst = true;
    setInterval(function() {
  
      var i = Math.floor(Math.random() * data.live_ev.length);
      var $basketball = $('.table-liveevents').find('tr:has(td:contains("Basketball"))');
  
      addRow(data.live_ev[i], $('.table-liveevents'));
  
      if ($basketball.length &gt; 0 &amp;&amp; isFirst==true) {
        $basketball.addClass("highlight").one('webkitAnimationEnd mozAnimationEnd msAnimationEnd oAnimationEnd animationend', function(){
          $(this).removeClass("highlight");
        });
        isFirst = false;
      }
  
      $('.table-liveevents').trigger("update");    
  
    }, 3000);     
  
  }); 
  </code></pre>