我有一个非常基本的搜索功能,可以对名称列表进行排序。大约有4,000个名称,所以这个循环有点慢,以便在用户输入时跟上。以下是每个新搜索值的循环:
elements.each(function(i, el){
var name = $(el).find('button').text();
name = name.toLowerCase();
if(name.indexOf(value) >= 0) {
$(el).show().addClass('visible');
}
else {
$(el).hide().removeClass('visible');
}
});
如何优化此循环以便跟上用户输入?
跟进: 根据用户建议,当文本输入获得焦点时,我将数据映射并存储在数组中。然后,我将主动搜索更改为以下内容:
Array.prototype.forEach.call(this.cache, function(el, i){
var name = el.name;
if(name.indexOf(value) >= 0) {
el.element.style.display = '';
el.element.classList.add('visible');
}
else {
el.element.style.display = 'none';
el.element.classList.remove('visible');
}
});
我试图在可以更好地优化的地方切断jQuery。它似乎没有任何明显的滞后现在工作!感谢您提出的很好的建议和讨论。
答案 0 :(得分:1)
如前所述@Taplar,您可以延迟错误检查。
并非所有内容都必须是实时的,因为它可能会损害可用性。
在系统停止接收操作后,在一个时间内检查一些东西是很常见的,当用户输入时,你可能只是灰显状态文本,并且在用户停止输入传递后500ms,你执行检查并为状态文本分配必要的类。
这是一个示例实现。它不会引发错误"除非你输入" BAD"在文本框中。
var timeout;
$("#txt").keydown(function(e){
$("#status").removeClass("bad").addClass("wait");
clearInterval(timeout);
timeout = setTimeout(checkStuff, 500);
});
function checkStuff(){
var t = $("#txt").val();
var s = $("#status");
s.removeClass("wait").html("No errors");
if(t.indexOf("BAD") > -1) {
s.addClass("bad").html("Errors detected!");
}
}

#status{
color:green;
}
#status.wait{
color:rgba(150,150,150,1);
}
#status.bad{
color:red;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="txt" placeholder="type plz"><br>
<span id="status">No errors</span>
&#13;
答案 1 :(得分:-3)
jQuery是sloooooooooooooooow,如果你可以在vanilla JS中进行循环和大部分重复的功能,你将节省大量的处理时间。预映射文本也是巨大的,查找按钮元素并且每次获取文本值都是一个很大的浪费。
/*
elements.each(function(i, el){
var name = $(el).find('button').text();
name = name.toLowerCase();
if(name.indexOf(value) >= 0) {
$(el).show().addClass('visible');
}
else {
$(el).hide().removeClass('visible');
}
});
*/
let elemQueryArr = elements.map(elem => {
return {
elem: elem,
text: elem.querySelector('button').text.toLowerCase()
}
}), len = elemQueryArr.length
function filterElems(val){
let i = -1
while(++i < len){
let elem = elemQueryArr[i]
if(elem.text.indexOf(val) > -1) elem.elem.classList.add('visible')
else elem.elem.classList.remove('visible')
}
}