2012-01-11 92 views
3

这里是我使用过的元素的无序列表进行排序,并根据用户的查询中删除了jQuery/Javascript代码:是否有可能优化Javascript客户端搜索?

// event binding for the search filter 
$('.search-box').keyup(function(){ 
    var query = $(this).val().toLowerCase(), 
     length = query.length; 

    $('.friends-list li').each(function(){ 
     if(query.length > 1 && $(this).find('span').text().toLowerCase().substring(0, length) != query){ 
      $(this).hide(); 
     } else { 
      $(this).show(); 
     } 
    }); 
}); 

不幸的是,当我获得了大量的锂元素,这相当缓慢,有时会挂在系统上。有没有一种方法来优化,或先做所有的搜索,然后一次删除li元素,这样系统就不会挂起?

当我做一个服务器端搜索时,我可以只有一个加载微调器和一个成功回调,但似乎并不适用于客户端。

+1

这只是随机弹出在我的流,很好的问题...采取upvote! – 2012-01-11 22:29:41

回答

4

一对夫妇提示

的火不要在每个keyup事件搜索。取而代之的是,有一个较短的计时器(200毫秒〜)是等待下一次KEYUP并开始搜索,如果有没有:

keyup: 
     clearTimeout(searchTimer) 
     searchTimer = setTimeout(doSearch, 200) 

如果您query.length <=1循环可以被优化掉,无需检查每个迭代。

each(li)...find(span)开销太多。尝试直接迭代直接跨越:

$('.friends-list li span').each(function() { 
    var p = $(this); 
    if(p.text().toLowerCase().indexOf(query) !== 0) { 
     p.parent().hide(); 
    } else { 
     p.show(); 
    } 
}); 

还要注意在上面的代码中的一些次要优化。

+0

我原则上同意你直接在跨度上循环,但是这确实假定没有没有子跨度的列表项目。如果这可以得到证实,那么是的,绝对是你的方式。 (另外,你可能的意思是'p.parent()。show();') – nnnnnn 2012-01-11 22:49:50

+0

@nnnnnn,你是对的,我们需要更多地了解他们的html布局。 – georg 2012-01-11 23:05:25

2

推迟DOM更新是加速这种代码的有效方式。最后完成它们,而不是在.each()循环中。

0

目前,您对每个关键笔画都进行全面搜索。您可能需要等待少量时间。说0.2秒,并检查是否有另一个键被按下。对于用户体验来说,小延迟应该是可以的,甚至几乎不可察觉,但是如果有人正在输入一个单词(快速连续按下键),这可以为您节省许多增​​加体验速度的迭代次数。

2

我建议延迟击键,直到用户停止输入一段时间 - 比如说半秒,尽管你可以尝试并调整它味道。此外,我对搜索进行了一些小改动,例如,如果您知道搜索字符串太短,您只想显示所有内容,因此无需在该情况下测试循环中的每个项目。

(function() { 
    var timerID = null; 

    function doSearch(query) { 
    var length = query.length; 

    if (length <= 1) { 
     $('.friends-list li').show(); 
    } else { 
     $('.friends-list li').each(function(){ 
      var $this = $(this); 
      if($this.find('span').text().toLowerCase() 
             .substring(0, length) != query) 
       $this.hide(); 
      else 
       $this.show(); 
     }); 
    } 
    } 

    $('.search-box').keyup(function(){ 
     var searchString = this.value.toLowerCase(); 

     if (timerID) 
     clearTimeout(timerID); 

     timerID = setTimeout(function() { 
     timerID = null; 
     doSearch(searchString); 
     }, 500); 
    }); 
)(); 
0

而且我知道这是旧的,但考虑到更好的选择,缓存元素和事件冒泡(这里不适用) - 搜索优化的jQuery,你会得到一堆的极好的提示。