Javascript 提高jqueryfind的性能

Javascript 提高jqueryfind的性能,javascript,jquery,Javascript,Jquery,我改编了教程中的以下代码,以根据li元素的内容过滤它们: $('#_selectSearch_' + index).keyup(function() { var filter = $(this).val(); if(filter) { $('#_selectDrop_' + index).find("li:not(:contains(" + filter + "))").slideUp(); $('#_selectDrop_'

我改编了教程中的以下代码,以根据li元素的内容过滤它们:

$('#_selectSearch_' + index).keyup(function() {
       var filter = $(this).val();
       if(filter) {
          $('#_selectDrop_' + index).find("li:not(:contains(" + filter + "))").slideUp();
          $('#_selectDrop_' + index).find("li:contains(" + filter + ")").slideDown();
       } else {
          $('#_selectDrop_' + index).find("li").slideDown();
       }
    });
代码工作得很好,但是处理大列表时速度非常慢,每按一次键,浏览器就会死机几秒钟。我环顾四周,得出结论,改进这一点的方法是以某种方式缓存列表,而不是直接在DOM上操作,但不知道如何实现这一点

drop = $('#_selectDrop_' + index + ' li');
$('#_selectSearch_' + index).keyup(function() {
   var filter = $(this).val();
   if(filter) {
      drop.find(":not(:contains(" + filter + "))").slideUp();
      drop.find(":contains(" + filter + ")").slideDown();
   } else {
      drop.slideDown();
   }
});

Drop将只缓存一次,然后在每次密钥更新时使用。此外,这还使用了
find

的最小可能值。您可以缓存此元素
$('#u selectDrop'+index+'li')

$('#_selectSearch_' + index).keyup(function() {

   var filter = $(this).val();

   // by combining and cacheing all the way to the li
   // we save a lot of time, since it seems that's where you are doing
   // all your searching from

   var selectDrop = $('#_selectDrop_' + index + ' li');

   if (filter) {
      selectDrop.not(':contains("' + filter + '")').slideUp();
      selectDrop.contains(filter).slideDown();
   } 
   else {
      selectDrop.slideDown();
   }
});

我将尝试使用经过一些修改(未经测试)的版本:

$('#_selectSearch_' + index).on('keyup', function() {
    var filter = this.value,
        lis = document.getElementById('_selectDrop_' + index).getElementsByTagName('li'),
        len = lis.length,
        sup = 'textContent' in this;
    if (filter.length) {
        for (var i = len; i--) {
            var text = sup ? lis[i].textContent : lis[i].innerText;
            $(lis[i])[text.indexOf(filter) != -1 ? 'slideDown' : 'slideUp']();
        }
    } else {
        $(lis).slideDown();
    }
});​

如果您主要关心的是性能,请执行以下代码:

  • 缓存包含筛选器字符串的元素
  • 缓存li元素
  • 不显示或隐藏已处于该状态的元素
  • 使用非常快的indexOf
  • 如果用户键入的字母间隔小于500毫秒,则showMatches将不会运行
  • var-selectSearch=$(“#_-selectSearch”+索引);
    var li=$(“#u选择Drop”+索引+“li”);
    var电流超时;
    选择Search.on(“键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键控键{
    if(currentTimeout){window.clearTimeout(currentTimeout)};
    currentTimeout=setTimeout(showMatches,500);
    });
    函数showMatches(){
    var txt=selectSearch.val();
    对于(变量i=0,len=li.length;i-1){
    if(li[i].style.display!=“块”){
    li[i].style.display=“block”;
    }
    }否则{
    if(li[i].style.display!=“无”){
    li[i].style.display=“无”;
    }
    }
    }
    }
    

    摆弄400 li元素

    这是一项练习,还是您需要现场/项目的信息?我这样问是因为答案会有所不同。最有可能的是slideUp和slideDown是性能问题发生的地方,而不是.find。但是,您可以使用.find+.filter或.not优化.find
    .find(“li”).not(“:contains(“+filter+”)”)@ChrisBurdon如果没有匹配项,是否显示所有项目。是吗?@Bruno如果没有匹配项,它应该显示一条消息,说明没有匹配项。我刚刚在《凯文B》中加上了这句话。@Kevin B-谢谢,你说的对,大部分的表演热播都来自于slideUP和slideDown的台词。删除它们并隐藏元素的速度要快得多,列表看起来也不会更糟。
    .contains()
    方法用于检查另一个DOM元素中是否存在DOM元素,而不是检查在该元素中是否可以找到某些文本。
    $('#_selectSearch_' + index).on('keyup', function() {
        var filter = this.value,
            lis = document.getElementById('_selectDrop_' + index).getElementsByTagName('li'),
            len = lis.length,
            sup = 'textContent' in this;
        if (filter.length) {
            for (var i = len; i--) {
                var text = sup ? lis[i].textContent : lis[i].innerText;
                $(lis[i])[text.indexOf(filter) != -1 ? 'slideDown' : 'slideUp']();
            }
        } else {
            $(lis).slideDown();
        }
    });​
    
    var selectSearch = $("#_selectSearch_" + index );
    var li = $("#_selectDrop_" + index + " li");
    var currentTimeout;
    
    selectSearch.on( "keyup", function( ) {
        if( currentTimeout ) { window.clearTimeout( currentTimeout ) };
        currentTimeout = setTimeout( showMatches, 500 );
    
    });
    
    function showMatches( ) {
        var txt = selectSearch.val();
    
        for( var i = 0, len = li.length; i < len; i++ ) {
    
            var content = li[i].textContent ? li[i].textContent : li[i].innerText;
    
            if( txt && content.indexOf( txt ) > -1) {
                if( li[i].style.display !== "block" ) {
                    li[i].style.display = "block";
                }
            } else {
                if( li[i].style.display !== "none" ) {
                    li[i].style.display = "none";
                }
            }
        }
    }