我有一个自动填充表单,用户可以在其中键入一个术语,并隐藏所有不包含该术语的<li>
元素。
我最初使用jQuery <li>
遍历所有each
并将.hide()
应用于不包含该术语的<li>
。这太慢了。
我发现更快的方法是遍历所有.hidden
并将类$('.hidden').hide()
应用于需要隐藏的所有内容,然后在循环结束时执行.hidden
。但这有点像黑客。
可能更快的方法是使用document.styleSheets
重写{{1}}类的CSS规则。谁能想到更好的方法?
编辑:让我澄清一些我不确定太多人知道的事情。如果在循环的每次迭代中更改DOM,并且该更改导致重新绘制页面,那么这将比“准备”所有更改并在循环完成时立即应用它们慢得多。
答案 0 :(得分:23)
每当你处理成千上万的项目时,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似乎和任何一样好。)这是自动完成的;没有人真正查看所有结果 - 他们将继续输入,直到结果集对人类可管理。
答案 1 :(得分:1)
您可以直接选择所有&lt; li&gt; s,然后对其进行过滤:$("li").filter(function(){...}).hide()
(请参阅here)
(抱歉,我以前发错了)
答案 2 :(得分:1)
您可以使用jQuery contains()选择器查找列表中包含特定文本的所有项目,然后隐藏它们,如下所示:
HTML:
<ul id="myList">
<li>this</li>
<li>that</li>
<ul>
的jQuery
var term = 'this';
$('li:contains("' + term + '")').hide();
答案 3 :(得分:0)
怎么样:
<style>
.hidden{ display: none; }
</style>
这样你就不必使用$(&#39; .hidden&#39;)来进行额外的查询.hide()?
答案 4 :(得分:0)
您可以直接定义“隐藏”,而不是重新定义样式表规则 class属性为“display:none;”在手和你的页面之前,你可以 在通过javascript验证条件后应用您定义的类, 如下。
$("li").each(function(){if(condition){$(this).addClass('hide');}});
以后,如果你想再次显示那些li,你可以删除下面的类
$("li").each(function(){if(condition){$(this).removeClass('hide');}});
答案 5 :(得分:0)
您可以使用更独特的技术,在技术上不使用JavaScript来执行实际隐藏,方法是将数据的副本放在属性中,并使用CSS属性选择器。
例如,如果术语为secret
,并且您将数据的副本放在data-term
属性中,则可以使用以下CSS:
li[data-term*="secret"] {
display: none;
}
要动态执行此操作,您必须在javascript中添加样式到头部:
function hideTerm(term) {
css = 'li[data-term*="'+term+'"]{display:none;}'
style = $('<style type="text/css">').text(css)
$('head').append(style);
}
如果你这样做,你可能希望在停止使用它们时清理样式标签。
这可能是最快的,因为在现代浏览器中CSS选择非常快。我很难确定基准,所以我不能肯定地说。