搜索项目会导致滞后

时间:2015-10-13 15:46:11

标签: javascript jquery dom

我有以下问题。让我们说我有这样的DOM。

<div class="results">
  <div class="result">
    <div class="title">Aaa</div>
  </div>
  <div class="result filtered-out">
    <div class="title">Aab</div>
  </div>
  <div class="result">
    <div class="title">Aac</div>
  </div>
  <div class="result">
    <div class="title">Aad</div>
  </div>
  <div class="result">
    <div class="title">Aae</div>
  </div>
</div>

和这样的输入字段

<input type="text" id="search">

现在我尝试使用此

定义的简单函数过滤结果
var searchBox = $(this);
searchBox.keyup(function(){
  var searchBox = $(this);
  var items = $(".results .result:not(.filtered-out)");
  items.each(function(){
    var title  = $(this).find(".title").html();
    if(title.toLowerCase().indexOf(searchBox.val().toLowerCase())!== -1)
      $(this).show();
    else
      $(this).hide();
  });
});

所以问题是结果列表很长,介于100到200个元素之间,每当我在搜索输入中键入内容时,代码执行的时间就很长。也许大约2-3秒。有没有其他方法可以解决这个问题&#34;滞后&#34;?感谢您的任何建议!

编辑可能是延迟脚本执行或异步脚本执行(如ajax)?

4 个答案:

答案 0 :(得分:1)

当通过许多元素搜索dom时,如果你正在追求速度,建议使用javascript而不是jQuery。 jQuery有它的目的但是使用javascripts进行大量的dom搜索getElementById或querySelector / querySelectorAll将会快得多。如果你检查这个jsPerf example,你会发现jQuery选择器的运行速度比同类的getElementById慢大约94%。

答案 1 :(得分:1)

将DOM用作数据源通常不是一个好主意,它并不意味着它,因此很慢。我个人建议使用一个小的MVVM库或类似的东西,这样你就不必亲自手动管理DOM了 我在下面使用了Vue.js,但您也可以使用任何类似的解决方案。将数据保存在代码中将使您能够更快地对其进行操作,因为您不必一直重新请求它,并且您避免做大量的修改工作。以下所有操作均在1000个对象上完成:

var items = [];
for (var i = 0; i < 1000; i++) {
  items.push({
    title: 'Item #' + i
  });
}
var v = new Vue({
  el: '#list',
  data: {
    items: items,
    input: ""
  },
  computed: {
    filteredItems: function() {
      var value = ("" || this.input).trim().toLowerCase();
      if (!value.length) return this.items;
      return this.items.filter(function(item) {
        return item.title.toLowerCase().indexOf(value) !== -1;
      });
    }
  }
});
ol {
  list-style: none;
  padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/0.12.16/vue.min.js"></script>
<div id="list">
  <input placeholder="Search" v-model="input" />
  <ol>
    <li v-repeat="filteredItems">{{title}}</li>
  </ol>
</div>

答案 2 :(得分:0)

您应该尝试使用一些日志记录来确定哪个部分占用时间最长。如果您发现它是items选择器(使用伪了 - 不是),您可以尝试对其进行优化,但是我没有看到filtered-out类的任何内容,所以我和#39;我不确定那是什么。

这里有一些简单的优化:

var searchBox = $(this);
searchBox.keyup(function(){
  var $searchBox = $(this);
  var searchBoxVal = $searchBox.val().toLowerCase();
  var items = $(".results .result:not(.filtered-out)");
  items.each(function(){
    var $item = $(this);
    var title  = $item.find(".title").html();
    if (title.toLowerCase().indexOf(searchBoxVal) !== -1)
      $item.show();
    else
      $item.hide();
  });
});

答案 3 :(得分:0)

我猜测滞后是因为您正在基于DOM元素执行搜索,同时通过隐藏/显示来操作它们。

我认为DOM是从某些数据源填充的?如果是这样,最好从该数据源执行搜索/过滤,然后使用过滤后的数据集再次填充DOM。 (即使您最初没有数据源,也可以通过阅读原始DOM来构建一个数据源)