0

问题


我正在注册一个 keyup 事件,当它被激活时,会显示一个建议主题的列表(使用 JSON)。

我的问题是,当一个 keyup 被注册时,它似乎也能记住以前的 keyup。这意味着它不是使用 JSON 发送一个请求,而是使用 JSON 发送多个请求(取决于已注册的 keyup 数量)。这当然是非常低效的,我想每个 keyup 只处理 1 个请求。

我试过什么


我已经尝试逐步执行程序采取的每一个动作。当我到达第二个 keyup 语句时出现问题(第一个是在我的模板中注册一个 keyup,第二个是我正在使用的类中的一个 keyup,它从指定的字段中检索值)。从这一点开始,每个键都以某种方式“添加”到以前的键中,例如:按下了
3 个先前的键 -> (示例)按下了退格键 -> 现在为退格键注册了 4 个键键,所有键都包含相同的信息。

我已经尝试设置语句等来检查以前的事件是否与当前事件相同,但这真的没有奏效。该类在不同的站点上工作,所以我认为问题出在其他地方,可能是模板(它包含另一个注册 keyups 的事件,但完全删除它不会改变任何东西)是随着时间的推移由不同的程序员创建的(它有点像虽然我看不到任何应该造成这种奇怪行为的东西)。

相关代码


模板代码:

$('subject_input').addEvent('keyup', function(event){
    var project_id = $('projectId').options[$('projectId').selectedIndex].get('value');

    if(project_id != "" && project_id != 0){ //Als er een project geselecteerd is 
        var elInput = $('subject_input');

        var gc = new GooCompleter('subject_input', {
            action: '/houroverview/ajax_subjects/'+project_id+'/',  // JSON source 
            param: 'search',            // Param string to send 
            listbox_offset: {x: 0, y: 0},   // Listbox offset for Y 
            typebox_offset: {x: 1, y: 1},
            delay: 100,                     // Request delay to 0.1 seconds 
        });
//Irrelevant code

                });

类代码keyup:

 // Retrieve suggestions on keyup
    this.field.addEvent('keyup', function(event) {
        console.log(event); //this shows the amount of keyups etc.
        //more code
    }.bind(this));

我应该指出,我对 JavaScript 并不是那么好,这意味着我要花很多时间来弄清楚一些东西。我仍然在这段代码中看不到任何会产生这种奇怪行为的东西。

问题


是什么导致了这种奇怪的行为,我该如何摆脱它?

干杯。

4

2 回答 2

1

是的,根据您的代码,每个键盘输入似乎都会发出一个新请求。这不是奇怪的行为,正是您的代码所做的。浏览器说每次 keyup 发生时都会发生 keyup(在键盘上释放任何键),并且您的代码会发送一个请求作为对每个 keyup 的反应。

当他们回来时,您可以忽略除最后一个之外的所有内容,但您也可以更有效,并且在用户停止输入(例如 500 毫秒)之前不发送任何请求。

$('subject_input').addEvent('keyup', throttle( function(event) {
    //Once no keyup has happened for 500ms, this function is then called normally
}, 500 ));

油门定义:

function throttle( fn, timeout ) {
    var timerid = 0;

    return function() {
        clearTimeout(timerid);

        var args = [].slice.call(arguments),
            ctx = this;

        timerid = setTimeout( function() {
            fn.apply( ctx, args );
        }, timeout );

    };
}
于 2012-08-06T09:48:03.233 回答
1

根据文档,GooCompleter它自己监视按键。您只需要初始化一次(例如在domready事件处理程序中)。

在您当前的实现中,每个按键都会创建一个新实例GooCompleter,因此在例如 10 次按键之后有 10GooCompleter秒,每次监控按键并发送 AJAX 请求(这样后续按键将在 10GooCompleter秒内发送 10 次 AJAX 请求) .

于 2012-08-06T10:43:06.300 回答