什么';在javascript中查找tbody行的最佳方法是什么?正则表达式还是。。。?

什么';在javascript中查找tbody行的最佳方法是什么?正则表达式还是。。。?,javascript,jquery,regex,Javascript,Jquery,Regex,我要做的是过滤一个表,只显示包含给定值的tbody和输入到文本框中的值,并以斑马线模式显示过滤后的行 斑马条纹是快速的,过滤通常是快速的,除了在一个有很多tbody的桌子上的第一个过滤器上(比如说2000 tbody?…我没有测量第一个可见的减速,也没有通过数字测试速度,但在Firefox和Chrome中速度很慢) 首先是JS: //filter results based on query function filter(selector, query) { var regex = new

我要做的是过滤一个表,只显示包含给定值的tbody和输入到文本框中的值,并以斑马线模式显示过滤后的行

斑马条纹是快速的,过滤通常是快速的,除了在一个有很多tbody的桌子上的第一个过滤器上(比如说2000 tbody?…我没有测量第一个可见的减速,也没有通过数字测试速度,但在Firefox和Chrome中速度很慢)

首先是JS:

//filter results based on query
function filter(selector, query) {
  var regex = new RegExp( query, "i" ); // I did this from memory, may be incorrect, but I know the thing works, the problem is the next part, cos on 5 rows it's fast
  $(selector).each(function() {
    ( regex.test( $(this).text() ) ) < 0) ? $(this).hide().removeClass('visible') : $(this).show().addClass('visible');
  });
}
// then after this I recall the zebra function, which is fast.
//根据查询筛选结果
函数过滤器(选择器、查询){
var regex=new RegExp(query,“i”);//我是从内存中做的,可能不正确,但我知道这是可行的,问题是下一部分,因为在5行上它很快
$(选择器)。每个(函数(){
(regex.test($(this.text())<0)?$(this.hide().removeClass('visible'):$(this.show().addClass('visible');
});
}
//然后我回忆起zebra函数,它很快。
然后,样本数据:

<table>
 <thead>
  <tr>
    <th>value to find 1</th>
    <th>value to find 2</th>
  </tr>
 </thead>
 <tbody>
  <tr>
    <td>12345</td>
    <td>67890</td>
  </tr>
  <tr>
    <td>empty for now, while testing</td>
    <td>may contain other info later</td>
  </tr>
 </tbody>
 <tbody>
  <tr>
    <td>23456</td>
    <td>78901</td>
  </tr>
  <tr>
    <td></td>
    <td></td>
  </tr>
 </tbody>
 <tbody>
  <tr>
    <td>45678</td>
    <td>90123</td>
  </tr>
  <tr>
    <td></td>
    <td></td>
  </tr>
 </tbody>

... /ad nauseum, for 2000 rows +

 <tfoot>
 </tfoot>
</table>

找到1的值
找到2的值
12345
67890
测试时暂时清空
以后可能会包含其他信息
23456
78901
45678
90123
... /阿德瑙瑟姆,2000排+
例如,尝试匹配value
123
将返回此示例数据的第一行和第三行,但我认为您已经发现了

帮助?

只是一个想法,这(双关语)更快吗


我认为最好对一组数据使用过滤函数,这将是一个对象数组。然后从过滤后的数据提供程序重建表


显示/隐藏表行存在固有的问题,其中最重要的问题是不同的浏览器(我在看你,IE)执行不同的隐藏操作。仅仅将行设置为visibility=“hidden”并不能满足您的需要。将其设置为display=“none”将起作用,但您将无法将其取回。在这种情况下,您将显示样式设置为什么?当然不是“阻塞”。将其设置为“表行”在浏览器中的行为不同

每当您使用这么多DOM元素时,您的主要性能问题通常是呈现,因为每次您在DOM中修改某些内容时,浏览器都会重新呈现页面。这将使渲染性能变为O(n^2),除非修改DOM之外的元素。有几种方法可以做到这一点,比如克隆和DOM数组。要使用克隆,请
克隆
要修改的元素,修改克隆的元素,然后使用
替换
将它们插入DOM。DOM数组只是包含DOM元素的标准JavaScript数组。可以将DOM元素数组传递给jQuery,而不是选择器。这是我使用html副本进行的测试的输出。我正在使用jquery1.4.2

// Using chrome 6.0.472.62
Number of <td> elements: 9524
Optimized Time: 232ms
Normal Time: 21669ms
//使用chrome 6.0.472.62
元素数:9524
优化时间:232ms
正常时间:21669毫秒
其他现代浏览器具有不同的性能特征

// Using IE8
Number of <td> elements: 9524
Optimized Time: 1506ms
Normal Time: 4179ms

// Using Firefox 4 Beta
Number of <td> elements: 9524
Optimized Time: 698ms
Normal Time: 2644ms
//使用IE8
元素数:9524
优化时间:1506ms
正常时间:4179ms
//使用Firefox4测试版
元素数:9524
优化时间:698ms
正常时间:2644ms
您可以看到O(n^2)渲染是如何开始累积的。这是我的测试程序减去了数千个复制的html元素

$(document).ready(function(){
  console.log("Number of <td> elements: " + $("td").length);

  $('input[value=clone]').click(function(){
    function filter(selector, query) {
      var regex = new RegExp( query, "i" );
      var temp = $("table").clone();
      var hide = [];
      var show = [];
      $(selector, temp).each(function() {
        if (regex.test($(this).text())) {
          hide.push(this);
        } else {
          show.push(this);
        }
      });
      $(hide).hide().removeClass('visible');
      $(show).show().addClass('visible');
      $("table").replaceWith(temp);
    }
    var start = (new Date).getTime();
    /* Run a test. */
    filter("td","12345");
    var diff = (new Date).getTime() - start;
    console.log("Optimized Time: " + diff + "ms");
  });

  $('input[value=normal]').click(function(){
    function filter(selector, query) {
      var regex = new RegExp( query, "i" );
      $(selector).each(function() {
        if (regex.test($(this).text())) {
          $(this).hide().removeClass('visible');
        } else {
          $(this).show().addClass('visible');
        }
      });
    }
    var start = (new Date).getTime();
    /* Run a test. */
    filter("td","12345");
    var diff = (new Date).getTime() - start;
    console.log("Normal Time: " + diff + "ms");
  });
});
$(文档).ready(函数(){
log(“元素数:+$(“td”).length);
$('input[value=clone]')。单击(函数(){
函数过滤器(选择器、查询){
var regex=新的RegExp(查询“i”);
var temp=$(“表”).clone();
var hide=[];
var-show=[];
$(选择器,临时)。每个(函数(){
if(regex.test($(this.text())){
隐藏。推(这个);
}否则{
展示。推(这个);
}
});
$(hide.hide().removeClass('visible');
$(show).show().addClass('visible');
$(“表”)。替换为(临时);
}
var start=(新日期).getTime();
/*运行测试*/
过滤器(“td”、“12345”);
var diff=(新日期).getTime()-start;
log(“优化时间:+diff+“ms”);
});
$('input[value=normal]')。单击(函数(){
函数过滤器(选择器、查询){
var regex=新的RegExp(查询“i”);
$(选择器)。每个(函数(){
if(regex.test($(this.text())){
$(this.hide().removeClass('visible');
}否则{
$(this.show().addClass('visible');
}
});
}
var start=(新日期).getTime();
/*运行测试*/
过滤器(“td”、“12345”);
var diff=(新日期).getTime()-start;
日志(“正常时间:+diff+“ms”);
});
});

如果不想克隆,另一种选择是分离正在处理的元素,然后在完成后重新连接它们。请参阅。

好的评论。我每次都考虑从头开始重建它,希望得到一些意见,因为我周末一直在考虑这个问题。有什么想法吗?应该是jQuery通过show()和hide()处理跨浏览器问题,对吗?@drachenstein:这是我能想到的唯一一种非笨拙的方式来获得替代行颜色(斑马条纹)。否则,每次都必须遍历它们,这可能比重建更麻烦@Hogan:据我所知,jQuery会正确处理这个问题,但这仍然是一个痛苦和消耗,渲染可能不会比重建快太多。我个人不会将2000行加载到浏览器中,而是使用AJAX来获取数据——但问题是基于一篇使用jQuery显示和隐藏行的文章——所以这是一个安全的选择。jQuery就是这样,它让疯狂的跨浏览器内容变得简单(在本例中可能更简单。)@Hogan@Robusto~加载多达40k行进行排序。。。我觉得这样做会更快
// Using IE8
Number of <td> elements: 9524
Optimized Time: 1506ms
Normal Time: 4179ms

// Using Firefox 4 Beta
Number of <td> elements: 9524
Optimized Time: 698ms
Normal Time: 2644ms
$(document).ready(function(){
  console.log("Number of <td> elements: " + $("td").length);

  $('input[value=clone]').click(function(){
    function filter(selector, query) {
      var regex = new RegExp( query, "i" );
      var temp = $("table").clone();
      var hide = [];
      var show = [];
      $(selector, temp).each(function() {
        if (regex.test($(this).text())) {
          hide.push(this);
        } else {
          show.push(this);
        }
      });
      $(hide).hide().removeClass('visible');
      $(show).show().addClass('visible');
      $("table").replaceWith(temp);
    }
    var start = (new Date).getTime();
    /* Run a test. */
    filter("td","12345");
    var diff = (new Date).getTime() - start;
    console.log("Optimized Time: " + diff + "ms");
  });

  $('input[value=normal]').click(function(){
    function filter(selector, query) {
      var regex = new RegExp( query, "i" );
      $(selector).each(function() {
        if (regex.test($(this).text())) {
          $(this).hide().removeClass('visible');
        } else {
          $(this).show().addClass('visible');
        }
      });
    }
    var start = (new Date).getTime();
    /* Run a test. */
    filter("td","12345");
    var diff = (new Date).getTime() - start;
    console.log("Normal Time: " + diff + "ms");
  });
});