Jquery - 延迟搜索直到输入完成

时间:2017-02-01 14:27:25

标签: javascript jquery

我希望延迟搜索的触发器,直到用户完成输入。我正在使用用mark.js(https://markjs.io)构建的函数。它作为用户类型进行搜索,并在搜索时跳转到第一个结果。问题是它会在您键入时搜索每个字母组合。 I.E:搜索“帮助”搜索“h”,“he”,“hel”,“help”。鉴于文件的大小,这是非常慢的。我可以用这个功能让它等到用户完成输入吗?

这是我正在使用的搜索功能:

    $(function() {

  // the input field
  var $input = $("input[type='search']"),
    // clear button
    $clearBtn = $("button[data-search='clear']"),
    // prev button
    $prevBtn = $("button[data-search='prev']"),
    // next button
    $nextBtn = $("button[data-search='next']"),
    // the context where to search
    $content = $(".container"),
    // jQuery object to save <mark> elements
    $results,
    // the class that will be appended to the current
    // focused element
    currentClass = "current",
    // top offset for the jump (the search bar)
    offsetTop = 150,
    // the current index of the focused element
    currentIndex = 0;

  /**
   * Jumps to the element matching the currentIndex
   */
  function jumpTo() {
    if ($results.length) {
      var position,
        $current = $results.eq(currentIndex);
      $results.removeClass(currentClass);
      if ($current.length) {
        $current.addClass(currentClass);
        position = $current.offset().top - offsetTop;
        window.scrollTo(0, position);
      }
    }
  }

  /**
   * Searches for the entered keyword in the
   * specified context on input
   */
  $input.on("input", function() {
    var searchVal = this.value;
    $content.unmark({
      done: function() {
        $content.mark(searchVal, {
          accuracy: "exactly",
          separateWordSearch: false,
          done: function() {
//Filter Results//$context.not(":has(mark)").hide();
            $results = $content.find("mark");
            currentIndex = 0;
            jumpTo();
          }
        });
      }
    });
  });

  /**
   * Clears the search
   */
  $clearBtn.on("click", function() {
    $content.unmark();
    $input.val("").focus();
  });

  /**
   * Next and previous search jump to
   */
  $nextBtn.add($prevBtn).on("click", function() {
    if ($results.length) {
      currentIndex += $(this).is($prevBtn) ? -1 : 1;
      if (currentIndex < 0) {
        currentIndex = $results.length - 1;
      }
      if (currentIndex > $results.length - 1) {
        currentIndex = 0;
      }
      jumpTo();
    }
  });
});

以下是一些HTML:

<input type="search" placeholder="Search" class="text-input" style="height: 28px; border-style: solid; border-color: black; border-width: 1px; margin-bottom: 3px;">
      <br/>
      <button data-search="next">Next</button>
      <button data-search="prev">Previous</button>
      <button data-search="clear">✖</button><br/>
<div class="container">
   <div>
     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus elementum non arcu id tristique. Cras fringilla nisi erat, non ultricies leo varius eu. Duis venenatis enim sed tristique gravida. Nulla dolor augue, tempor non nisl eget, consequat consequat magna. Nulla quis elit nisl. Integer at tortor molestie, dignissim odio id, pharetra nunc. Maecenas scelerisque porta erat bibendum aliquet. Proin est felis, pretium sit amet consequat eu, aliquet ac erat. Donec tempus, libero sit amet rutrum posuere, leo ipsum gravida odio, quis sodales magna nisl ut lectus.
   </div>
</div>

4 个答案:

答案 0 :(得分:1)

您可以使用计时器限制搜索功能的初始化,并检查是否存在最少数量的字符

类似的东西:

var searchTimer = null,
  minLength = 3,
  searchDelay = 300;

$input.on("input", function() {
  // clear previous timer
  clearTimeout(searchTimer);

  var searchVal = this.value;

  // don't do anything if not enough characters
  if (searchVal.length < minLength) {
    return;
  }  

  // start new timer
  searchTimer = setTimeout(function() {
    $content.unmark({
      done: function() {
        $content.mark(searchVal, {
          accuracy: "exactly",
          separateWordSearch: false,
          done: function() {
            //Filter Results//$context.not(":has(mark)").hide();
            $results = $content.find("mark");
            currentIndex = 0;
            jumpTo();
          }
        });
      }
    });
  }, searchDelay);
});

答案 1 :(得分:1)

您可以按下 Enter 键并调用搜索功能后的单词调用搜索功能。

例如:

$input.on("input", function(e) {

    if (e.which == 13) {
        var searchVal = this.value;
        $content.unmark({
            done: function() {
                $content.mark(searchVal, {
                    accuracy: "exactly",
                    separateWordSearch: false,
                    done: function() {
                        $results = $content.find("mark");
                        currentIndex = 0;
                        jumpTo();
                    }
                });
            }
        });
    }
}

答案 2 :(得分:0)

您需要延迟计时器。基本上,当用户按下某个键时,启动计时器而不是直接调用搜索功能。如果用户再次按下键,则启动计时器。如果计时器结束,请进行搜索。

[INSTALLFOLDER]servers.cfg

工作示例:https://jsfiddle.net/mspinks/13uxa86p/2/

答案 3 :(得分:0)

我刚为你写了一个小函数:

  function simpleDelayTimer() {
  var delay = 2000;
  var timer = null;
  return {
    start:
    function () {
      this.timer = setTimeout(function () {
        alert('Put Code here');
      }, delay);
      return timer;
    },
    reset: function () {
      clearTimeout(this.timer);
    }
  }
}
  
  var timer = simpleDelayTimer();
  
  
  function startTimer(){
    if (document.getElementById('timertest').value.trim() == "")
        return;
    
    timer.reset();
    timer.start();
  }
  
  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="timertest">Type here </label> 
<input type="text" id="timertest" placeholder="2000ms timer" onkeyup="startTimer()" />

您可以在“setTimeout”

的函数体中放置一个functin或代码