【问题标题】:Can I delay the keyup event for jquery?我可以延迟 jquery 的 keyup 事件吗?
【发布时间】:2012-04-15 12:30:17
【问题描述】:

我将 rottentomatoes 电影 API 与 twitter 的 typeahead 插件结合使用,使用 bootstrap 2.0。我已经能够整合 API,但我遇到的问题是,在每个 keyup 事件之后,API 都会被调用。这一切都很好而且很花哨,但我宁愿在稍停片刻后拨打电话,让用户先输入几个字符。

这是我当前在 keyup 事件后调用 API 的代码:

    var autocomplete = $('#searchinput').typeahead()
    .on('keyup', function(ev){

        ev.stopPropagation();
        ev.preventDefault();

        //filter out up/down, tab, enter, and escape keys
        if( $.inArray(ev.keyCode,[40,38,9,13,27]) === -1 ){

            var self = $(this);

            //set typeahead source to empty
            self.data('typeahead').source = [];

            //active used so we aren't triggering duplicate keyup events
            if( !self.data('active') && self.val().length > 0){

                self.data('active', true);

                //Do data request. Insert your own API logic here.
                $.getJSON("http://api.rottentomatoes.com/api/public/v1.0/movies.json?callback=?&apikey=MY_API_KEY&page_limit=5",{
                    q: encodeURI($(this).val())
                }, function(data) {

                    //set this to true when your callback executes
                    self.data('active',true);

                    //Filter out your own parameters. Populate them into an array, since this is what typeahead's source requires
                    var arr = [],
                        i=0;

                    var movies = data.movies;

                     $.each(movies, function(index, movie) {
                        arr[i] = movie.title
                        i++;
                     });

                    //set your results into the typehead's source 
                    self.data('typeahead').source = arr;

                    //trigger keyup on the typeahead to make it search
                    self.trigger('keyup');

                    //All done, set to false to prepare for the next remote query.
                    self.data('active', false);

                });

            }
        }
    });

是否可以设置一个小的延迟并避免在每次按键后调用 API?

【问题讨论】:

    标签: jquery twitter-bootstrap onkeyup


    【解决方案1】:

    可以这样轻松完成:

    var autocomplete = $('#searchinput').typeahead().on('keyup', delayRequest);
    
    function dataRequest() {
        // api request here
    }
    
    function delayRequest(ev) {
        if(delayRequest.timeout) {
            clearTimeout(delayRequest.timeout);
        }
    
        var target = this;
    
        delayRequest.timeout = setTimeout(function() {
            dataRequest.call(target, ev);
        }, 200); // 200ms delay
    }
    

    【讨论】:

    • 这很好用,但似乎卡在一个循环中,每 200 毫秒调用一次 datarequest?
    • 在您的代码中,您在 keyup 之后触发了 keyup:self.trigger('keyup')。对于正确的 keyup 事件处理,您应该删除 ev.stopPropagation();self.trigger('keyup')
    【解决方案2】:

    一般来说,这可以通过setTimeoutclearTimeout 方法来实现:

    var timer;
    
    $('#textbox').keyup(function() {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout('alert("Something cool happens here....");', 500);
    });
    

    setTimeout 将在指定的毫秒间隔后执行提供的 javascript。 clearTimeout 将取消此执行。

    我还准备了jsFiddle demo,展示了运行中的代码 sn-p。

    参考资料:

    【讨论】:

      【解决方案3】:

      对于使用 v0.11 of typeahead.js 并使用 Bloodhound 获取远程建议的人,您可以使用 rateLimitWait 选项来限制请求:

      var search = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
          url: '/search?q=%QUERY',
          rateLimitWait: 500
        }
      });
      

      【讨论】:

        【解决方案4】:

        不确定 Bootstrap 2.0 使用哪个版本进行预输入,但 v0.9.3 有一个隐藏在后台的 minLength 选项,但没有记录。

        $('#people').typeahead({
          name: 'people',
          prefetch: './names.json',
          minLength: 3
        });
        

        从这篇博文中发现:http://tosbourn.com/2013/08/javascript/setting-a-minimum-length-for-your-search-in-typeahead-js/

        【讨论】:

          【解决方案5】:

          而不是延迟,如果您只想允许用户在 ajax $.getJSON 请求之前输入几个字符,您可以修改 if 语句,以便用户必须输入最少数量的字符,例如3、在请求数据之前:

          if( !self.data('active') && self.val().length >=3){
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-05-12
            • 1970-01-01
            • 2012-07-16
            • 2012-01-14
            • 2017-02-22
            • 1970-01-01
            • 2011-01-17
            相关资源
            最近更新 更多