隐藏成千上万个元素的最快方法?

我有一个自动填充表单,用户可以在其中键入一个术语,并隐藏所有不包含该术语的

  • 元素。

    我最初使用jQuery循环遍历所有

  • 并将.hide()应用于不包含该术语的那些。 这太慢了。

    我发现更快的方法是循环遍历所有

  • 并将类.hidden应用于所有需要隐藏的东西,然后在循环结束时执行$('.hidden').hide() 。 这虽然感觉有些苛刻。

    一种可能更快的方法可能是使用document.styleSheets重写.hidden类的CSS规则。 有谁能想到更好的方法?

    编辑:让我澄清一些我不确定太多人知道​​的事情。 如果在循环的每次迭代中更改DOM,并且该更改导致重新绘制页面,那么这将比“准备”所有更改慢得多,并在循环结束时立即应用它们。

    每当你处理成千上万的项目时,DOM操作都会很慢。 循环遍历许多DOM元素并基于该元素的特性操纵每个元素通常不是一个好主意,因为这涉及在每次迭代中对DOM方法的大量调用。 如你所见,它真的很慢。

    更好的方法是将数据与DOM分开。 搜索JS字符串数组要快几个数量级。

    这可能意味着将数据集作为JSON对象加载。 如果这不是一个选项,你可以循环

  • 一次(在页面加载时),并将数据复制到一个数组中。

    现在您的数据集不依赖于存在的DOM元素,您可以在每次用户键入时使用.html()简单地替换

      的全部内容。 (这比JS DOM操作快得多,因为当您只是更改innerHTML时,浏览器可以优化DOM更改。)

       var dataset = ['term 1', 'term 2', 'something else', ... ]; $('input').keyup(function() { var i, o = '', q = $(this).val(); for (i = 0; i < dataset.length; i++) { if (dataset[i].indexOf(q) >= 0) o+='
    • ' + dataset[i] + '
    • '; } $('ul').html(o); });

      如您所见 ,这非常快。


      但是,请注意,如果将其增加到10,000个项目 ,性能开始受到前几次击键的影响。 这与插入到DOM中的结果数量相关,而不是与搜索的原始数量相关。 (当你输入更多,并且显示的结果较少时,性能很好 – 即使它仍在搜索所有10,000个项目。)

      为避免这种情况,我会考虑将显示的结果数量限制为合理的数字。 (1000似乎和任何一样好。)这是自动完成的; 没有人真正查看所有结果 – 他们将继续输入,直到结果集对人类可管理。

      你可以直接选择所有

    • ,然后过滤它们: $("li").filter(function(){...}).hide() (见这里 )
    • (对不起,我之前发错了)

      您可以使用jQuery contains()选择器查找列表中包含特定文本的所有项目,然后隐藏它们,如下所示:

      HTML:

        
      • this
      • that

      jQuery的

       var term = 'this'; $('li:contains("' + term + '")').hide();​ 

      我知道这个问题很老但是我对任何答案都不满意。 目前我正在开发一个使用jQuery Selectable列表的Youtube项目,该列表有大约120,000个项目。 这些列表可以按文本过滤,而不是显示相应的项目。 隐藏所有不匹配元素的唯一可接受的方法是首先隐藏ul元素,而不是隐藏li元素并再次显示list(ul)元素。

      怎么样:

        

      这样你就不必使用$(’。hidden’)进行额外的查询.hide()?

      您可以直接将“hide”类属性定义为“display:none;”,而不是重新定义Stylesheets规则。 在手和页面之前,您可以通过javascriptvalidation条件后应用您定义的类,如下所示。

       $("li").each(function(){if(condition){$(this).addClass('hide');}}); 

      然后,如果你想再次显示那些li,你可以删除下面的类

       $("li").each(function(){if(condition){$(this).removeClass('hide');}}); 

      您可以使用更独特的技术,在技术上不使用JavaScript来执行实际隐藏,方法是将数据的副本放在属性中,并使用CSS属性选择器。

      例如,如果术语是secret ,并且您将数据的副本放在data-term属性中,则可以使用以下CSS:

       li[data-term*="secret"] { display: none; } 

      要动态执行此操作,您必须在javascript中向头部添加样式:

       function hideTerm(term) { css = 'li[data-term*="'+term+'"]{display:none;}' style = $(' 

      如果你这样做,你会希望在停止使用它们时清理样式标签。

      这可能是最快的,因为在现代浏览器中CSS选择非常快。 它很难进行基准测试,所以我不能肯定地说。

      Interesting Posts