【问题标题】:php/jquery search boxphp/jquery 搜索框
【发布时间】:2012-03-13 09:14:41
【问题描述】:

我正在尝试使用 php 和 jquery 实现搜索框(搜索结果来自数据库)。我想要做的是,当用户在搜索框中键入内容时,会进行查询以查找包含用户在搜索框中输入的关键字的数据。我遇到的问题是我有这样的事情:

$("#my_search_box").keyup(function(){

    retrieve_results($(this).val());    

});

这样做的问题是,每次用户完成输入时都会调用函数retrieve_results()(当然,因为这就是keyup 的用途)。因此,这可能会变得非常慢,因为如果用户键入一个包含 10 个字符的单词,retrieve_results() 函数会连续调用 10 次。另外,我应该提到,在我的retrieve_results() 函数中,我正在使用jQuery $.ajax 执行Ajax 请求以获取结果。所以我的问题如下:

我如何做到这一点,以便我的函数 retrieve_results() 不会在每次用户停止输入时(每次按键启动时)都被执行。我想保留该功能,但我不希望用户单击“搜索”按钮或其他东西。我只是希望我的retrieve_results() 函数在用户输入完所有关键字后仅被调用一次(不是每次用户输入字母或其他内容时)

谢谢

【问题讨论】:

    标签: php jquery ajax search search-engine


    【解决方案1】:

    您可以启动一个计时器...让我们说...在第一个键之后...如果间隔大于 2 秒(键之间)进行搜索,否则等待 http://api.jquery.com/delay/

    示例(来自To delay JavaScript function call using jQuery):

      $("#button").bind("sample",function() {
          sample();
        });
    
        $("#button").click(function(){
          $(this).delay(2000).trigger("sample");
        });
    

    没有时间测试 delay

    替代品(已测试) 3 分钟内完成,很晚(当地时间凌晨 2:12)

    $("#my_search_box").keyup(function(){
                setTimeout(search, 30000);
    });
    function search(){
            alert('ok');
    }
    

    【讨论】:

    • 如果我的函数需要参数,我如何在 setTimeout 函数中传递这些参数?
    • 但是,我的函数仍然被称为 keyup 执行的次数。所有这一切都是在延迟我的函数的执行,就像我上面所说的,我希望我的函数retrieve_results() 只被调用一次
    • 所有这些都是延迟搜索 30000 毫秒,但它仍然会在每次击键时触发。例如:如果用户输入chrysanthemum,这个脚本将等待30000ms然后触发search() 13次。
    【解决方案2】:

    我建议使用 jQuery 中的 delay 方法或 JavaScript 中的 setTimeout() 函数,其中间隔将在每次执行 keyup 方法时重置为原始间隔。 Here is a brief explanation 的 setTimeout() 方法和 JavaScript 中的其他几个计时器方法。

    【讨论】:

      【解决方案3】:

      像这样的事情应该这样做。您创建一个全局变量来存储查询,并创建另一个变量来了解是否有足够的时间来重新调用retrieve_results。您在每次键入时更新 searchQuery,但只在您想要的时间之后执行 retrieve_results。希望对你有帮助。

          searchQuery="";
          timeIsUp=true;
      
          $("#my_search_box").keyup(function(){
      
            searchQuery=$(this).val();
      
            if(timeIsUp){
              timeIsUp=false;
              setTimeOut("retrieve_results(searchQuery); timeIsUp=true",500); 
            }
      
          });
      

      【讨论】:

      • 我希望这不是不礼貌的,我不能在第一个答案中发表评论,我认为你可以做得更好。您不需要调用 clear time out ,就像在第一个答案中一样,如果另一个正在运行,您只需要不创建新的 setTimeOut 并将 searchQuery 存储在一个变量中,以便最后一次更改始终是那个正在寻找。它比创建和销毁大量计时器更有效。
      • 如果您没有使用明确的超时并且只是没有触发,即使用户还没有完成输入,搜索仍然会触发。因此,假设他输入查询需要 5 秒,而不是等到他完成,搜索将触发 10 次(500 毫秒)或 5 次,等待 1000 毫秒。使用 clearTimeout,搜索将在用户完成输入 1000 毫秒后等待触发。这在服务器上更轻。
      • 真的,对不起。这在服务器上会更轻,这是真的。
      【解决方案4】:

      理想情况下,您只想搜索用户键入的最后一个字符。做到这一点的最好方法是给他足够的时间不断地打字,如果他停下来(甚至思考),就开始搜索。 单独使用setTimeout 是行不通的,因为即使这样也会触发多次。您必须使用clearTimeout 清除超时。

      您可以使用以下方法来达到预期的效果:

      $(document).ready(function() {
          var timeout,
              $search_box = $('#my_search_box');
      
          $search_box.keyup(function() {
              if (timeout) {
                  clearTimeout(timeout);
              }
      
              timeout = setTimeout(function() {
                  search();
              }, 1000);
          });
      
          function search() {
              var search_txt = $search_box.val();
          }
      });
      

      以下是正在发生的事情: 我们将setTimeout 计时器分配给一个变量,该变量必须在您的keyup 函数上方声明,并在每次keyup 触发时检查该变量。如果有一个现有的 setTimeout 正在进行中,请将其清除以使其不会触发 search() 函数并创建一个新的计时器集以等待指定的毫秒数(在我的示例中为 1000)。

      请参阅以下 JSFiddle 进行演示:http://jsfiddle.net/highwayoflife/WE4Fr/

      【讨论】:

      • 非常感谢,你是那个人,但问题是,为什么我每次都必须清除计时器?
      • @user765368 我们仅在存在正在运行的“超时”函数时才清除超时。如果我们没有清除此超时,则每次按键都会触发您的搜索,仅延迟 1000 毫秒。你可以试试......在jsfiddle中,删除if (timeout) ... 代码并运行脚本。您会注意到每次按键都会在 1 秒后触发搜索功能。
      猜你喜欢
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 2017-05-15
      • 1970-01-01
      相关资源
      最近更新 更多