限制$ .get()请求

时间:2014-07-24 17:20:28

标签: jquery ajax

我定义了一个每次按下一个键时执行get请求的函数:

$('.form-control').keypress(function() {
    var o = $('#origin').val();
    var d = $('#destination').val();

    $('#directions').html('Wait, please...');

    $.get('/search', { origin: o, destination: d })
        .done(function(data) {
            $('#origin-info').html($('#origin').val());
            $('#destination-info').html($('#destination').val());

            $('#directions').html(data);
        });
    }
});

然而,这是非常低效的,因为它每按一次键就会执行整个get请求。我不想在用户输入时查看所有请求。合乎逻辑的是限制给定一定时间或设置计时器的请求数量。然后当用户停止输入时,将执行最后一个请求。

我看了get()的jQuery文档,但我没有看到这样的选项。

最好的方法是什么,我应该怎么做?

1 个答案:

答案 0 :(得分:5)

你有正确的想法。你没有在get的文档中看到它,因为它不是它的工作,它是你的代码调用 get的工作:

var timer = 0;
$('.form-control').keypress(function() {
    clearTimeout(timer);
    timer = setTimeout(handleKeypress, 200);
});
function handleKeypress() {
    var o = $('#origin').val();
    var d = $('#destination').val();

    timer = 0;

    $('#directions').html('Wait, please...');

    $.get('/search', { origin: o, destination: d })
        .done(function(data) {
            $('#origin-info').html($('#origin').val());
            $('#destination-info').html($('#destination').val());

            $('#directions').html(data);
        });
    }
}

在那里,我们从timer变量开始,其值为0(因为0是一个无效的计时器句柄clearTimeoutsilently ignore)。当用户按下一个键时,我们清除任何先前的计时器并设置一个计时器,以便稍后调用我们的功能200ms(五分之一秒)。如果用户没有按另一个键,200ms后我们就会打电话;但如果他们这样做,计时器会被取消(再次),我们会安排一个新计时器。


附注:以上假设您只有.form-control,就像您的代码中的情况一样。但是假设您有几个,get中有关该怎么做的信息存储在.form-control上?上面的内容是不合适的,因为键入其中一个,按Tab键转到下一个,然后键入下一个将阻止第一个执行其工作。

在这种情况下,您可以使用jQuery的data

}存储在元素本身上。
$('.form-control').keypress(function() {
    var $this = $(this),
        timer = $this.data("keypress-timer");
    clearTimeout(timer); // clearTimeout will ignore `undefined`, so this is fine the first time
    timer = setTimeout(handleKeypress.bind(null, $this), 200);
});
function handleKeypress(control) {
    var container = control.closest(".container");
    var origin = container.find(".origin");
    var destination = container.find(".destination");
    var directions = container.find(".directions");
    var o = origin.val();
    var d = destination.val();

    control.data("keypress-timer", 0);

    directions.html('Wait, please...');

    $.get('/search', { origin: o, destination: d })
        .done(function(data) {
            container.find('.origin-info').html(o);
            container.find('.destination-info').html(d);

            directions.html(data);
        });
    }
}

请注意,这只是一个假设的例子,假设它们在某种容器中,您可以在同一个容器中找到其他相关字段......