2010-08-23 78 views
3

以下函数需要至少3秒才能运行(在500个表行上)。是否有可能使此功能更快?功能很慢,有没有更快的方法? (使用jQuery 1.4.2)

function prepareTable() { 
    var groupIndex = 0; 
    $("#row tbody tr").each(function(index) { 
    // each row gets a unique id 
    // remove default css styles for table rows 
    // read out hidden value, that stores if row is a group 
    var group = $(this).attr('id', 'node-'+index).removeClass("odd event").find('td :hidden').attr('value'); 
    // if it is a group, add special styles to row and remember row index 
    if (group == 'true') { 
     groupIndex = index; 
     $(this).addClass('odd').find("td:first") 
      .mouseenter(function() { 
       $(this).parent().addClass("swGroupLink"); 
      }) 
      .mouseleave(function() { 
       $(this).parent().removeClass("swGroupLink"); 
     }); 
    } else { 
     // make all following rows to children of the previous group found 
     $(this).addClass('even child-of-node-' + groupIndex); 
    } 
    }); 
} 
+0

全部500个表行是可见的,还是你使用分页? – 2010-08-23 07:00:55

+0

我也在使用分页。 thx的提示... – Steven 2010-08-23 07:18:57

+0

然后你可以做只处理表的可见部分。 – 2010-08-23 07:29:37

回答

6

我建议两方面的改进:

  • 缓存DOM References
  • 工作在你的餐桌离线

function prepareTable() { 
    var groupIndex = 0; 
    var $mytable = $('#row'), 
     $parent = $mytable.parent(); 

    $mytable = $mytable.detach(); 

    $mytable.find('tr').each(function(index) { 
     var $this = $(this); 
     var group = $this.attr('id', 'node-'+index).removeClass("odd event").find('td :hidden').attr('value'); 
// if it is a group, add special styles to row and remember row index 
    if (group == 'true') { 
     groupIndex = index; 
     $this.addClass('odd').find("td:first") 
      .mouseenter(function() { 
       $this.parent().addClass("swGroupLink"); 
      }) 
      .mouseleave(function() { 
       $this.parent().removeClass("swGroupLink"); 
     }); 
    } else { 
     // make all following rows to children of the previous group found 
     $this.addClass('even child-of-node-' + groupIndex); 
    } 
    }); 

    $parent.append($mytable); 
} 

我添加了一个变量$this,它将$(this)缓存在您的.each()循环中。我还加入了$mytable$parent$mytable存储#row元素,$parent存储#row的父节点。这是因为我从DOM中删除了整个元素,完成这些工作并将其重新附加到父级。

测试环境:http://www.jsfiddle.net/2C6fB/4/

如果仍然太慢,你还有其他选择这里。首先,看看你是否可以将循环分成更小的部分。您可以使用asychronous回调来优化,例如setTimeout。这可能是一个棘手的业务,我需要更详细地了解您的代码,但通常情况下,您可能只想将整个循环包装到单个setTimeout()函数中。示例 - >http://www.jsfiddle.net/2C6fB/5/

这可确保浏览器在操作时不会“挂起”。但是,当然这需要更长的时间才能完成整个任务。

+0

您的优化对我来说听起来非常好。不幸的是,该功能现在慢了大约20%:-( (使用Firebug和Google Chrome开发者工具进行测试) – Steven 2010-08-23 07:22:19

+0

@Steven:这听起来几乎不可能,我正在建立一个快速测试环境。 – jAndy 2010-08-23 07:32:23

+0

@jAndy:非常感谢。我也很困惑...... – Steven 2010-08-23 07:41:32

-1

我猜测发现是所有时间都消失的。

你能不能找到它的选择器吗?什么是HTML?

+0

为所有500行找到需要80ms – Steven 2010-08-23 07:40:10

1

您可以将带鼠标的mouseenter和mouseleave带到实时事件的外面,这样它就不会用prepareTable函数执行,并且您可以将它放入文档就绪函数中。

$("#row tbody tr td.trueInPrepareTable") 
    .live("mouseenter", function(event){  
       $(this).parent().addClass("swGroupLink");  
    }).live("mouseleave", function(event){  
       $(this).parent().removeClass("swGroupLink");  
    }); 

不是从隐藏字段获取组值,而是将此值放在rel,rev或title属性中。

function prepareTableEdit() { 
       var groupIndex = 0; 
       $("#row tbody tr").each(function(index) { 
        groupIndex = index; 
        $(this).attr('id', 'node-'+ groupIndex).removeClass("odd even"); 
        if($(this).attr('rel') == 'true') 
        {       
         $(this).addClass('odd').find("td:first").addClass('trueInPrepareTable');      } 
        else 
        { 
         $(this).addClass('even child-of-node-' + groupIndex).find("td:first").removeClass('trueInPrepareTable'); 
        } 
       }); 

} 

退房http://www.jsfiddle.net/raBGq/

+0

不错的主意,但几乎相同的执行时间(-100至-200毫秒) – Steven 2010-08-23 07:31:15

+0

检查出http://www.jsfiddle.net/raBGq/。它运行了160毫秒,比你的要快得多。您需要打开萤幕控制台才能查看结果。 – 2010-08-24 06:22:01

+0

你的新版本忽略了“子节点 - ” – Steven 2010-08-24 08:35:42