我有一个自动完成表单,用户可以在其中输入一个术语,它隐藏了所有不包含该术语的<li>
元素。
我最初使用jQuery的each
遍历所有<li>
,并将.hide()
应用于不包含该术语的那些。
我发现一个更快的方法是遍历所有的<li>
,并将类.hidden
应用于所有需要隐藏的对象,然后在循环结束时执行$('.hidden').hide()
。
一个可能更快的方法是使用document.styleSheets
重写.hidden
类的CSS规则。有人能想到更好的方法吗?
编辑:让我澄清一些我不确定太多人知道的事情。如果你在循环的每次迭代中修改DOM,并且修改导致页面被重绘,这将比“准备”所有修改并在循环结束时一次性应用它们慢得多。
8条答案
按热度按时间swvgeqrz1#
当你处理成千上万的项目时,DOM操作会很慢。循环遍历许多DOM元素并根据元素的特征操作每个元素通常不是一个好主意,因为这涉及到在每次迭代中对DOM方法的大量调用。正如你所看到的,它真的很慢。
一个更好的方法是将你的 * 数据 * 与DOM分开。通过JS字符串数组进行搜索要快几个数量级。
这可能意味着将数据集作为JSON对象加载。如果这不是一个选项,您可以循环
<li>
s一次(在页面加载时),并将数据复制到数组中。现在你的数据集不依赖于DOM元素的存在,你可以在用户每次输入时使用
.html()
简单地替换<ul>
的整个内容。(这比JS DOM操作快得多,因为浏览器可以在你简单地更改innerHTML
时优化DOM更改。)字符串
As you can see,这是非常快的。
但是,请注意,如果您使用up it to 10,000 items,那么在最初的几次搜索中,性能开始受到影响。这与插入到DOM中的结果数量有关,而不是与搜索的原始项目数量有关。(当您输入更多时,显示的结果较少,性能很好-即使它仍然搜索所有10,000个项目。)
为了避免这种情况,我会考虑将显示的结果数量限制在一个合理的数量。(1,000似乎和任何数量一样好。)这是自动完成的;没有人真正查看所有的结果-他们会继续输入,直到结果集对人类来说是可管理的。
ctehm74n2#
我知道这是一个老问题,但我对任何答案都不满意。目前我正在做一个Youtube项目,它使用了jQuery Selectable list,大约有120.000个条目。这些列表可以通过文本过滤,然后显示相应的条目。隐藏所有不匹配元素的唯一可接受的方法是先隐藏ul元素,而不是隐藏li元素,然后显示列表(ul)。元素中。
dly7yett3#
您可以直接选择所有s,然后过滤它们:
$("li").filter(function(){...}).hide()
(参见here)(对不起,我之前发错了)
vi4fp9gy4#
你可以使用jQuery contains()选择器来查找列表中包含特定文本的所有项目,然后隐藏它们,就像这样:
超文本标记语言:
字符串
jQuery
型
ioekq8ef5#
您可以使用一种更独特的技术,在技术上不使用JavaScript来进行实际隐藏,方法是将数据的副本放在属性中,并使用CSS属性选择器。
例如,如果术语是
secret
,并且您将数据的副本放在data-term
属性中,则可以使用以下CSS:字符串
要动态地做到这一点,你必须在JavaScript中为head添加一个样式:
型
如果你要这样做,你会希望确保在停止使用它们时清理样式标记。
这可能是最快的,因为CSS选择在现代浏览器中是非常快的。这将是很难基准,所以我不能肯定,虽然。
wwtsj6pe6#
怎么样:
字符串
这样你就不必使用$('. hidden').hide()进行额外的查询了?
xmakbtuz7#
你可以直接定义'hide' class属性为“display:none;”,而不是重新定义样式表规则,在你的页面中,你可以在通过JavaScript验证条件后应用你定义的类,如下所示。
字符串
以后,如果你想再次显示那些li,你可以像下面这样删除类
型
mf98qq948#
在新创建的样式表上使用
insertRule
:字符串
我还没有对此进行基准测试,但假设内部浏览器代码可能比JavaScript循环快一点。
我知道你提到了文档。样式表,但这是一个更孤立的方法。