我有以下问题。让我们说我有这样的DOM。
<div class="results">
<div class="result">
<div class="title">Aaa</div>
</div>
<div class="result filtered-out">
<div class="title">Aab</div>
</div>
<div class="result">
<div class="title">Aac</div>
</div>
<div class="result">
<div class="title">Aad</div>
</div>
<div class="result">
<div class="title">Aae</div>
</div>
</div>
和这样的输入字段
<input type="text" id="search">
现在我尝试使用此
定义的简单函数过滤结果var searchBox = $(this);
searchBox.keyup(function(){
var searchBox = $(this);
var items = $(".results .result:not(.filtered-out)");
items.each(function(){
var title = $(this).find(".title").html();
if(title.toLowerCase().indexOf(searchBox.val().toLowerCase())!== -1)
$(this).show();
else
$(this).hide();
});
});
所以问题是结果列表很长,介于100到200个元素之间,每当我在搜索输入中键入内容时,代码执行的时间就很长。也许大约2-3秒。有没有其他方法可以解决这个问题&#34;滞后&#34;?感谢您的任何建议!
编辑可能是延迟脚本执行或异步脚本执行(如ajax)?
答案 0 :(得分:1)
当通过许多元素搜索dom时,如果你正在追求速度,建议使用javascript而不是jQuery。 jQuery有它的目的但是使用javascripts进行大量的dom搜索getElementById或querySelector / querySelectorAll将会快得多。如果你检查这个jsPerf example,你会发现jQuery选择器的运行速度比同类的getElementById慢大约94%。
答案 1 :(得分:1)
将DOM用作数据源通常不是一个好主意,它并不意味着它,因此很慢。我个人建议使用一个小的MVVM库或类似的东西,这样你就不必亲自手动管理DOM了 我在下面使用了Vue.js,但您也可以使用任何类似的解决方案。将数据保存在代码中将使您能够更快地对其进行操作,因为您不必一直重新请求它,并且您避免做大量的修改工作。以下所有操作均在1000个对象上完成:
var items = [];
for (var i = 0; i < 1000; i++) {
items.push({
title: 'Item #' + i
});
}
var v = new Vue({
el: '#list',
data: {
items: items,
input: ""
},
computed: {
filteredItems: function() {
var value = ("" || this.input).trim().toLowerCase();
if (!value.length) return this.items;
return this.items.filter(function(item) {
return item.title.toLowerCase().indexOf(value) !== -1;
});
}
}
});
ol {
list-style: none;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.16/vue.min.js"></script>
<div id="list">
<input placeholder="Search" v-model="input" />
<ol>
<li v-repeat="filteredItems">{{title}}</li>
</ol>
</div>
答案 2 :(得分:0)
您应该尝试使用一些日志记录来确定哪个部分占用时间最长。如果您发现它是items
选择器(使用伪了 - 不是),您可以尝试对其进行优化,但是我没有看到filtered-out
类的任何内容,所以我和#39;我不确定那是什么。
这里有一些简单的优化:
var searchBox = $(this);
searchBox.keyup(function(){
var $searchBox = $(this);
var searchBoxVal = $searchBox.val().toLowerCase();
var items = $(".results .result:not(.filtered-out)");
items.each(function(){
var $item = $(this);
var title = $item.find(".title").html();
if (title.toLowerCase().indexOf(searchBoxVal) !== -1)
$item.show();
else
$item.hide();
});
});
答案 3 :(得分:0)
我猜测滞后是因为您正在基于DOM元素执行搜索,同时通过隐藏/显示来操作它们。
我认为DOM是从某些数据源填充的?如果是这样,最好从该数据源执行搜索/过滤,然后使用过滤后的数据集再次填充DOM。 (即使您最初没有数据源,也可以通过阅读原始DOM来构建一个数据源)