【问题标题】:How does the AutoSuggest feature for tags in StackOverflow avoid querying on every key strokeStackOverflow 中标签的 AutoSuggest 功能如何避免在每次击键时查询
【发布时间】:2010-12-13 22:05:51
【问题描述】:

我正在尝试使用 Jquery 实现类似的功能,例如自动建议功能,用于在本网站的文本区域下方可用的标签。我试图弄清楚请求是如何在几次击键后发送的,而不是在每次击键后发送的。我正在使用“keyup”事件来触发我的应用程序上的请求。我意识到这可能会导致过多的服务器命中并可能影响性能。

如果有人能解释我如何通过不在每个 keyup 上运行查询来实现 stackOverflow 所做的事情,那就太棒了。

【问题讨论】:

  • 我试图不使用插件。

标签: jquery autocomplete autosuggest


【解决方案1】:

我的一个 Windows 应用程序中有一个类似的功能。当用户键入一个字符时,一个计时器以 1 秒的间隔启动。在 Tick 事件中,开始搜索。如果用户再次键入,则重新启动计时器。因此,仅当键盘空闲超过一秒时才会执行搜索。

简短示例(使用 C#,但很容易理解):

public partial class Form1 : Form
{
    private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

    public Form1()
    {
        InitializeComponent();

        timer.Interval = 1000;
        timer.Tick += new EventHandler(timer_Tick);
    }

    void timer_Tick(object sender, EventArgs e)
    {
        timer.Stop();

        // Do search, or what ever you want to do
        Console.WriteLine("Searching...");
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (timer.Enabled)
        {
            timer.Stop();
        }

        timer.Start();
    }
}

我在 Javascript 方面没有经验,但我认为来自 here 的答案会对您有所帮助:

<input name="domain" type="text" id="domain" onKeyUp="javascript:chk_me();">

var timer;
    function chk_me(){

       clearTimeout(timer);
       timer=setTimeout(function validate(){...},1000);
    }

【讨论】:

  • 谢谢菲利普。那么我将如何管理时间戳。我是否需要类变量之类的东西来维护最后一个时间戳。我是 javascript 的新手,虽然我每天都使用它。是否可以不创建 Javascript 类
  • 看看这个问题中接受的答案:stackoverflow.com/questions/1381751/…
【解决方案2】:
var activity = new ActivityTimer(1000, function() {
    doSearch();
});

$("#searchBox").keyup(function(){ activity.reset() });

function ActivityTimer(deadline, callback) {
    var timer = -1;

    this.reset = function() {
        this.cancel();
        timer = setTimeout(callback, deadline);
    };

    this.cancel = function() {
        if(timer >= 0) {
            clearTimeout(timer);
            timer = -1;
        }
    };
}

【讨论】:

    【解决方案3】:

    您所指的方法称为“去抖动”

    我通常在所有脚本的底部都有一个“去抖动”功能

    var debounce=function(func, threshold, execAsap) {
        var timeout;
        return function debounced () {
            var obj = this, args = arguments;
            function delayed () {
                if (!execAsap)
                    func.apply(obj, args);
                timeout = null; 
            };
            if (timeout)
                clearTimeout(timeout);
            else if (execAsap)
                func.apply(obj, args);
            timeout = setTimeout(delayed, threshold || 100); 
        }; 
    };
    

    然后每当我做任何可以从去抖动中受益的事情时,我都可以通用地使用它

    所以你的代码会写成

    $("#search_box").keyup(debounce(function() {
        //do stuff in this function  
    }
    ,350 /*determines the delay in ms*/
    ,false /*should it execute on first keyup event, 
           or delay the first event until 
           the value in ms specified above*/
    ));
    

    查看Facebook Style AJAX Search 了解类似的用例...

    【讨论】:

      猜你喜欢
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多