我有一个自动填充表单,用户可以在其中键入一个术语,并隐藏所有< li>不包含该术语的元素.
我最初循环了所有< li>使用jQuery的每个并且将.hide()应用于不包含该术语的那些.这样太慢了.
我发现更快的方法是循环遍历所有< li>并将所有需要隐藏的类应用于.hidden,然后在循环结束时执行$(‘.hidden’).hide().这感觉很骇人听闻.
可能更快的方法可能是使用document.styleSheets重写.hidden类的CSS规则.有人会想到一个更好的方法吗?
编辑:让我澄清一点,我不知道太多人知道.如果您在循环的每次迭代中更改DOM,并且该更改导致页面被重新绘制,那将比“准备”所有更改更慢,并在循环完成时立即应用它们.
解决方法
每当你处理数以千计的项目时,DOM操纵都会很慢.循环遍历很多DOM元素并根据该元素的特征来操作每个元素通常不是一个好主意,因为这涉及到在每次迭代中对DOM方法的大量调用.正如你所看到的,真的很慢
一个更好的方法是保持数据与DOM分离.通过一系列JS字符串进行搜索比几个数量级更快.
这可能意味着将数据集加载为JSON对象.如果这不是一个选项,您可以循环遍历< li>一次(页面加载),并将数据复制到数组中.
现在您的数据集不依赖于存在的DOM元素,您可以简单地替换< ul>每次用户键入时使用.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+='<li>' + dataset[i] + '</li>'; } $('ul').html(o); });
As you can see,这是非常快的.
不过请注意,如果您在up it to 10,000 items,性能开始受到初次击键的影响.这与正在搜索的项目的原始数量相比,插入到DOM中的结果数量更多. (当您输入更多,并且显示的结果较少时,性能就会很好 – 即使它仍在搜索所有10,000个项目.)
为了避免这种情况,我会考虑将显示的结果数量限制在合理的数字上. (1000个似乎和任何一样好.)这是自动完成;没有人真正在寻找所有的结果 – 他们将继续打字,直到结果集可以管理一个人.