jQuery自动完成:用户输入中缺少字符

时间:2012-11-19 15:22:36

标签: javascript jquery jquery-autocomplete

我正在“城市”输入字段上调试jQuery自动填充实例(v1.1)。

自动填充数据绑定在字段的keyup事件中设置,仅当字段值长度至少为2时且仅在值已更改时才设置。

数据绑定,提示列表和自动完成工作正常。 但有些事情是错的。在日志中,我看到很多次第3个,有些甚至第4个字符在发布到服务器的城市输入值中缺失。一些例子:

"trpani" instead of "trapani"
"fienze" instead of "firenze"
"scndicci" instead of "scandicci"
"brdisi" instead of "brindisi"
"paermo" instead of "palermo"
"caliari" instead of "cagliari"

我没有成功复制这个bug,但我确信它不可能是偶然的!错误发生在第3个字符处。似乎在插入期间,Javascript处理与键盘缓冲区碰撞

所以,我猜,但我不确定,人们输入f i r e n z e,但最终错过了r字符,输入的最终值是最终发布的fienze到服务器。

问题

发生了什么事?为什么我没有成功复制错误?有什么问题?

以下是用于设置自动填充的代码:

/*
 * here I store the previous value
 */
var storeCity;
$('#City').keydown(function(){
    var val = $(this).val();
    storeCity = (val.length >=2 ? val.substring(0,2):"");
});

/*
 * the autocomplete is set only if
 * - the City value has changed compared to the storeCity value
 * - the City value has lenght at least 2
 * - remark: using the keypress does not solve the issue
 */
$('#City').keyup(function(){
    var val = $(this).val();
    if(val.length>=2 && val.substring(0,2)!=storeCity){
        getLocations('#City');
    }
});

function getLocations(cityId){
    var hint = $(cityId).val().substring(0,2);

    $.ajax({
        type: "GET",
        url: "/include/getLocations.asp",
        data: ({location : hint}),
        async: false,
        error: function() {},
        success: function(dataget) {
            var result = dataget.split("\n");

            $(cityId).flushCache();
            $(cityId).autocomplete(result, {
                pleft: 100px,
                minChars: 2,
                matchContains: true,
                max: 3000,
                delay: 100,
                formatItem: function(row){...},
                formatMatch: function(row){ return row[0]; },
                formatResult: function(row){ return row[0]; }
            });

            $(cityId).result(function(event,data){...});
        }
    });
}

2 个答案:

答案 0 :(得分:0)

看起来初始化的顺序应该反转。加载页面时,自动完成组件的初始化应该只发生一次。见附例:

  $( "#city" ).autocomplete({
        source: function( request, response ) {
           // Put your ajax request here
        }
  });

答案 1 :(得分:0)

最终我解决了一些启发式问题。我认为问题是由于事件冲突造成的。所以我试着获得更好的表现。

  • 在getLocation()方法之外初始化自动填充一次
  • 将$('#city')对象存储在变量
  • 将$ city.result方法放在getLocation()方法之外

以下是结果代码:

var $city = $('#City');
var storeCity;

$city.keypress(function(){
    var val = $(this).val();
    storeCity = (val.length >=2 ? val.substring(0,2):"");
});

/*
 * the autocomplete is set only if
 * - the City value has changed compared to the storeCity value
 * - the City value has lenght at least 2
 * - remark: using the keypress does not solve the issue
 */
$city.keyup(function(){
    var val = $(this).val();
    if(val.length>=2 && val.substring(0,2)!=storeCity){
        getLocations('#' + $city[0].id);
    }
});

$city.autocomplete({
    pleft: 100px,
    minChars: 2,
    matchContains: true,
    max: 3000,
    delay: 50
});

$city.result(function(event,data){...});

function getLocations(cityId){
    var hint = $(cityId).val().substring(0,2);

    $.ajax({
        type: "GET",
        url: "/include/getLocations.asp",
        data: ({location : hint}),
        async: false,
        error: function() {...},
        success: function(dataget) {
            var result = dataget.split("\n");

            $(cityId).flushCache();
            $(cityId).autocomplete(result, {
                formatItem: function(row){...},
                formatMatch: function(row){ return row[0]; },
                formatResult: function(row){ return row[0]; }
            });
        }
    });
}