使用javascript或jquery创建实时搜索的有效方法是什么? [英] What is the efficient way to create a live search using javascript or jquery?

查看:63
本文介绍了使用javascript或jquery创建实时搜索的有效方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实时搜索10000多行数据集.我已经提到了可用的dom结构.尽管我尝试在一次输入后就对每个结果进行实时搜索检查,但是我的浏览器正在挂起.还有什么其他有效的方法可以降低它的复杂性.

I was making a live search for more than 10000 rows of the dataset. I have mentioned the available dom structure. Although I try to make a live search check every result after a single input, my browser is getting hang. Is there any other efficient way that I can reduce its complexity.

<label class="label">
    <input type="checkbox" name="123" value="">
</label>
<label class="label">
    <input type="checkbox" name="123" value="   General AUX"> General AUX
</label>
<label class="label">
    <input type="checkbox" name="123" value=" Annser"> Annser
</label>
<label class="label">
    <input type="checkbox" name="123" value=" LRIPL"> LRIPL
</label>
<label class="label">
    <input type="checkbox" name="123" value=" Soy Impulse"> Soy Impulse
</label>

**是的,针对DOM进行实时搜索** 我用于实时搜索的JS代码

** Yes, live search against the DOM** JS code, that I am using for live search

 $(".form-container #filter").keyup(function() {
 var filter = $(this).val(),
                    count = 0;
                if(filter.length>=2){
                // Loop through the comment list
                $(".label").each(function() {

                    // If the list item does not contain the text phrase fade it out
                    if ($(this).text().search(new RegExp(filter, "i")) < 0) {
                        $(this).fadeOut();

                        // Show the list item if the phrase matches and increase the count by 1
                    } else {
                        $(this).show();
                        count++;
                        }
                 });
                // Update the count
                var numberItems = count;
                // $(".popopup-header").text(count + " results");
                //$("#filter-count").text(count + "results"); 
              }
            });

推荐答案

可以通过三种不同的方法来提高实时DOM搜索的性能. (我将考虑将给定的10000个DOM行呈现为固有的性能问题;此答案将仅涵盖搜索及其结果.)诸如使用.indexOf()而不是regexp之类的小细节也将有所帮助,但我想那种精细的细节并不是您真正的瓶颈.

There are three different ways you can improve the performance of a live DOM search. (I'm going to take the inherent performance issue with rendering 10000 DOM rows as a given; this answer will only cover the search and its results.) Small details such as using .indexOf() instead of a regexp will help as well, but I'd guess that sort of fine detail is not really your bottleneck.

实时搜索DOM总是比在简单数据对象上搜索慢得多.我猜想,这是迄今为止您目前最大的性能瓶颈.

Live-searching the DOM is always going to be much, much slower than searching against a simple data object. I'm going to guess that this is, by far, the biggest performance bottleneck you currently have.

看起来您只匹配每行一个字符串,这使事情变得更容易.如果您可以依赖于行的顺序从不改变,那么您就可以对这些字符串的简单数组进行搜索,而只需使用数组索引来指示您将隐藏或显示哪些DOM行(有关该内容的更多信息)稍后)-但如果行顺序可能会更改,则您需要为每个行至少包含一个ID,以便将字符串与正确的行进行匹配.所以最简单的情况可能是

It looks like you're only matching against a single string per row, which makes things easier. If you can depend on the order of your rows to never change, then you could get away with searching against a simple array of those strings, and just use the array index to indicate which DOM rows you'll hide or reveal (more about that later) -- but if the row order may change, you'll need to include at least an ID for each so you can match the string to the correct row. So the simplest case might be

var search = function(searchString) {
var searchableRows = ["General AUX", "Ansser", "Etcetera", ...]
var matchedSearch = [];
for (var i=0; i<searchableRows.length; i++) {
  if (searchableRows[i].indexOf(searchString) > -1) {
    matchedSearch[i]=1;
  }
}
// you'll use matchedSearch[] later to control which rows are visible.

减少搜索次数

您可以对输入进行反跳操作,以确保两次单独搜索之间的间隔至少为 n 毫秒,而不是对每个用户击键都进行搜索.某些框架具有内置的防反跳功能,但是滚动自己的框架非常简单.规范的插入示例可能是 David Walsh的,我无法对其进行改进:

Run the search less often

Instead of running the search on every user keystroke, you can debounce the input to guarantee at least n milliseconds between individual searches. Some frameworks have debounce functionality built in, but it's pretty simple to roll your own. The canonical drop-in example is probably this from David Walsh, which I cannot improve on:

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

更快地呈现结果

一个大型DOM操作要比许多小的DOM操作便宜.而且,为获得所需结果而更改DOM的次数越少越好.

Render the results more quickly

One big DOM operation is less expensive than lots of little DOM operations. And the less you have to change the DOM to get the results you want, the better.

因此,在搜索过程中逐步隐藏或删除DOM行的简单方法是肯定的.我可以想到的两种处理方法非常不同,老实说,我不确定哪种方法会更好.更好的选择可能取决于其他因素,例如HTML的复杂程度,是否需要保留js绑定,您愿意在javascript中生成多少等等,等等.

So the simple approach of incrementally hiding or removing DOM rows during the search -- that's out for sure. The two approaches I can think of to handle this are very different, and honestly I'm not sure which would have better performance; which is better may come down to other factors such as how complex the HTML needs to be and whether it has js bindings you need to preserve, how much of it you're comfortable generating within javascript, etc.

策略1:将结果html作为一个大字符串生成,然后将其放入DOM中以通过一次操作替换原始HTML:

So strategy 1: generate the results html as one big string and then drop that into the DOM to replace the original HTML in a single operation:

//assuming you have a filled matchedSearch array from above:
var searchResults = "";
for (var i=0; i<searchableRows.length; i++) {
  if (matchedSearch[i]) {
    searchResults = searchResults + '<label>...'+searchableRows[i]+'</label'>;
  }
}
document.getElementById('ResultsLocation').innerHTML(searchResults);

或者策略2采取相反的方法:一次渲染完整列表,并在每次搜索结束后将更改后的内容最小化.再次,这是在您完成matchedSearch数组的生成之后:

Or strategy 2 is to take the opposite approach: render the full list once, and minimize how much you change it after the fact for each search. Again, this would be after you've finished generating your matchedSearch array:

var allLabels = $('.label'); // I'm being lazy and depending on jQuery in this example
for (var i=0; i<allLabels.length; i++) {
  if (matchedSearch[i]) {
    allLabels[i].removeClass('hidden');
  } else {
    allLabels[i].addClass('hidden');
  }
}

(在显示方式上还有其他可能的优化方法-我注意到您当前正在使用.fadeOut();我不敢确定这是否比使用基于CSS类的动画要慢,但是值得一试.拥有这么多行,您可能还是会考虑忽略不必要的视觉效果.)

(There are other possible optimizations in how you display this -- I note you're using .fadeOut() currently; off the top of my head I'm not certain if that's slower than using a CSS class-based animation, but it'd be worth checking. With this many rows you might consider omitting unnecessary visual flourishes anyway.)

这篇关于使用javascript或jquery创建实时搜索的有效方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆