优化每个循环的jQuery

时间:2018-04-04 17:56:26

标签: javascript jquery

我有一个非常基本的搜索功能,可以对名称列表进行排序。大约有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。它似乎没有任何明显的滞后现在工作!感谢您提出的很好的建议和讨论。

2 个答案:

答案 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;
&#13;
&#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')
  }
}