我的自动完成触发次数太多

发布于 2024-11-03 05:47:08 字数 8515 浏览 0 评论 0原文

我在这里使用自动完成功能: http://blog.idealmind.com .br/geral/simple-autocomplete-jquery-plugin/

它有两个问题:

1)第一次在文本框中输入某些内容时它不起作用 - 不是一个大问题,因为你实际上并没有想要匹配单个字母 2)更恼人的是它发射的次数太多了。

我的 javascript 在这里:

<script type="text/javascript">
  function nameAutocomplete(field){
  alert($(field).val());
$("#name").simpleAutoComplete(
        'Ajax.action',
        {   'input': $(field).val(),
            '_eventName': 'getObjectsByAjax'
        },
        function(data){
        alert("we're in business");
        }
    );
}  
</script>

HTML 看起来像这样:

 <input type="text" name="name" id="name" size="45" class="medium-text" onkeyup="nameAutocomplete(this);"/>

这是插件(如下)的一部分,用于进行 Ajax 调用(工作正常):

            $.get(page, 
                {   'input': thisElement.val(),
                    '_eventName': 'getObjectsByAjax'
                },
                    function(res) 
                {
                $('div.' + classAC).remove();
                $("#autocomplete_tooltip").remove();
                var r="";
                var respObject=eval(res);
                r+="<ul>";
                for(var i in respObject)
                    {
                        r+='<li id="autocomplete_'+respObject[i].id+'"><table cellspacing=0 width="100%"><tr><td class="icon" width="20" uri="'+respObject[i].uri+'"><a href="/sempedia/Resource.action?id='+respObject[i].id+'" ><img src="images/green-file.png"></a></td><td class="caption">'+respObject[i].name+"</td></tr></table></li>";
                    }
                r+="</ul>";
                autoCompleteList = $('<div>').addClass(classAC).html(r);

我在这里打印了整个插件代码:

 (function($){
$.fn.extend(
{
    simpleAutoComplete: function( page, options, callback ) {
        if(typeof(page) == "undefined" ) {
            alert("simpleAutoComplete: Você deve especificar a página que processará a consulta.");
        }

        var classAC = 'autocomplete';
        var selClass = 'sel';
        var attrCB = 'rel';
        var thisElement = $(this);

        $(":not(div." + classAC + ")").click(function(){
            $("div." + classAC).remove();
            $("#autocomplete_tooltip").remove();
        });

        thisElement.attr("autocomplete","off");

        thisElement.keyup(function( ev )
        {   var getOptions = { input: thisElement.val() }

            if( typeof(options) == "object" )
            {
                classAC = typeof( options.autoCompleteClassName ) != "undefined" ? options.autoCompleteClassName : classAC;
                selClass = typeof( options.selectedClassName ) != "undefined" ? options.selectedClassName : selClass;

                attrCB = typeof( options.attrCallBack ) != "undefined" ? options.attrCallBack : attrCB;
                if( typeof( options.identifier ) == "string" )
                getOptions.identifier = options.identifier;

                if( typeof( options.extraParamFromInput ) != "undefined" )
                getOptions.extraParam = $( options.extraParamFromInput ).val();
            }

            kc = ( ( typeof( ev.charCode ) == 'undefined' || ev.charCode === 0 ) ? ev.keyCode : ev.charCode );
            key = String.fromCharCode(kc);

            console.log(kc, key, ev );

            if (kc == 27)
            {
                $('div.' + classAC).remove();
                $("#autocomplete_tooltip").remove();
            }
            if (kc == 13)
            {
                $('div.' + classAC + ' li.' + selClass).find(".caption").trigger('click');
            }
            if (key.match(/[a-zA-Z0-9_\- ]/) || kc == 8 || kc == 46)
            {
                $.get(page, 
                    {   'input': thisElement.val(),
                        '_eventName': 'getObjectsByAjax'
                    },
                        function(res) 
                    {
                    $('div.' + classAC).remove();
                    $("#autocomplete_tooltip").remove();
                    var r="";
                    var respObject=eval(res);
                    r+="<ul>";
                    for(var i in respObject)
                        {
                            r+='<li id="autocomplete_'+respObject[i].id+'"><table cellspacing=0 width="100%"><tr><td class="icon" width="20" uri="'+respObject[i].uri+'"><a href="/sempedia/Resource.action?id='+respObject[i].id+'" ><img src="images/green-file.png"></a></td><td class="caption">'+respObject[i].name+"</td></tr></table></li>";
                        }
                    r+="</ul>";
                    autoCompleteList = $('<div>').addClass(classAC).html(r);
                    if (r != '')
                    {
                        autoCompleteList.insertAfter(thisElement);

                        var position = thisElement.position();
                        var height = thisElement.height();
                        var width = thisElement.width();

                        $('div.' + classAC).css({
                            'top': ( height + position.top + 6 ) + 'px',
                            'left': ( position.left )+'px',
                            'margin': '0px'
                        });

                        $('div.' + classAC + ' ul').css({
                            'margin-left': '0px'
                        });

                        $('div.' + classAC + ' li').each(function( n, el )
                        {
                            el = $(el);
                            el.mouseenter(function(){
                                $('div.' + classAC + ' li.' + selClass).removeClass(selClass);
                                $(this).addClass(selClass);
                            });
                            el.find(".caption").click(function()
                            {
                                thisElement.attr('value', el.text());

                                if( typeof( callback ) == "function" )
                                    callback( el.attr(attrCB).split('_') );

                                $('div.' + classAC).remove();
                                thisElement.focus();
                            });

                            el.hover(function(e) {
                                urlText=$("<div>").attr("id","autocomplete_tooltip").addClass("tooltip").html($(this).find("td").attr("uri"));

                                urlText.css({
                                    position:"absolute",
                                    top:(e.pageY+20)+"px",
                                    left:(e.pageX+20)+"px"
                                    });

                                $("body").append(urlText);
                            },function() {
                                $("#autocomplete_tooltip").remove();
                            });


                        }); 
                    }
                });
            }
            if (kc == 38 || kc == 40){
                if ($('div.' + classAC + ' li.' + selClass).length == 0)
                {
                    if (kc == 38)
                    {
                        $($('div.' + classAC + ' li')[$('div.' + classAC + ' li').length - 1]).addClass(selClass);
                    } else {
                        $($('div.' + classAC + ' li')[0]).addClass(selClass);
                    }
                }
                else
                {
                    sel = false;
                    $('div.' + classAC + ' li').each(function(n, el)
                    {
                        el = $(el);
                        if ( !sel && el.hasClass(selClass) )
                        {
                        el.removeClass(selClass);
                        $($('div.' + classAC + ' li')[(kc == 38 ? (n - 1) : (n + 1))]).addClass(selClass);
                        sel = true;
                        }
                    });
                }
            }
            if (thisElement.val() == '') {
                $('div.' + classAC).remove();
                $("#autocomplete_tooltip").remove();
            }
        });
    }
});
  })(jQuery);

I am using the autocomplete here: http://blog.idealmind.com.br/geral/simple-autocomplete-jquery-plugin/

It has two problems:

1) It doesn't work the first time something is entered into textbox - not such a big problem, as you don't really want to match a single letter
2) The more irritating thing is that it fires too many times.

My javascript is here:

<script type="text/javascript">
  function nameAutocomplete(field){
  alert($(field).val());
$("#name").simpleAutoComplete(
        'Ajax.action',
        {   'input': $(field).val(),
            '_eventName': 'getObjectsByAjax'
        },
        function(data){
        alert("we're in business");
        }
    );
}  
</script>

The HTML looks like this:

 <input type="text" name="name" id="name" size="45" class="medium-text" onkeyup="nameAutocomplete(this);"/>

This is the part of the plugin (below) that makes the Ajax call (which is working fine):

            $.get(page, 
                {   'input': thisElement.val(),
                    '_eventName': 'getObjectsByAjax'
                },
                    function(res) 
                {
                $('div.' + classAC).remove();
                $("#autocomplete_tooltip").remove();
                var r="";
                var respObject=eval(res);
                r+="<ul>";
                for(var i in respObject)
                    {
                        r+='<li id="autocomplete_'+respObject[i].id+'"><table cellspacing=0 width="100%"><tr><td class="icon" width="20" uri="'+respObject[i].uri+'"><a href="/sempedia/Resource.action?id='+respObject[i].id+'" ><img src="images/green-file.png"></a></td><td class="caption">'+respObject[i].name+"</td></tr></table></li>";
                    }
                r+="</ul>";
                autoCompleteList = $('<div>').addClass(classAC).html(r);

I have printed the entire plugin code here:

 (function($){
$.fn.extend(
{
    simpleAutoComplete: function( page, options, callback ) {
        if(typeof(page) == "undefined" ) {
            alert("simpleAutoComplete: Você deve especificar a página que processará a consulta.");
        }

        var classAC = 'autocomplete';
        var selClass = 'sel';
        var attrCB = 'rel';
        var thisElement = $(this);

        $(":not(div." + classAC + ")").click(function(){
            $("div." + classAC).remove();
            $("#autocomplete_tooltip").remove();
        });

        thisElement.attr("autocomplete","off");

        thisElement.keyup(function( ev )
        {   var getOptions = { input: thisElement.val() }

            if( typeof(options) == "object" )
            {
                classAC = typeof( options.autoCompleteClassName ) != "undefined" ? options.autoCompleteClassName : classAC;
                selClass = typeof( options.selectedClassName ) != "undefined" ? options.selectedClassName : selClass;

                attrCB = typeof( options.attrCallBack ) != "undefined" ? options.attrCallBack : attrCB;
                if( typeof( options.identifier ) == "string" )
                getOptions.identifier = options.identifier;

                if( typeof( options.extraParamFromInput ) != "undefined" )
                getOptions.extraParam = $( options.extraParamFromInput ).val();
            }

            kc = ( ( typeof( ev.charCode ) == 'undefined' || ev.charCode === 0 ) ? ev.keyCode : ev.charCode );
            key = String.fromCharCode(kc);

            console.log(kc, key, ev );

            if (kc == 27)
            {
                $('div.' + classAC).remove();
                $("#autocomplete_tooltip").remove();
            }
            if (kc == 13)
            {
                $('div.' + classAC + ' li.' + selClass).find(".caption").trigger('click');
            }
            if (key.match(/[a-zA-Z0-9_\- ]/) || kc == 8 || kc == 46)
            {
                $.get(page, 
                    {   'input': thisElement.val(),
                        '_eventName': 'getObjectsByAjax'
                    },
                        function(res) 
                    {
                    $('div.' + classAC).remove();
                    $("#autocomplete_tooltip").remove();
                    var r="";
                    var respObject=eval(res);
                    r+="<ul>";
                    for(var i in respObject)
                        {
                            r+='<li id="autocomplete_'+respObject[i].id+'"><table cellspacing=0 width="100%"><tr><td class="icon" width="20" uri="'+respObject[i].uri+'"><a href="/sempedia/Resource.action?id='+respObject[i].id+'" ><img src="images/green-file.png"></a></td><td class="caption">'+respObject[i].name+"</td></tr></table></li>";
                        }
                    r+="</ul>";
                    autoCompleteList = $('<div>').addClass(classAC).html(r);
                    if (r != '')
                    {
                        autoCompleteList.insertAfter(thisElement);

                        var position = thisElement.position();
                        var height = thisElement.height();
                        var width = thisElement.width();

                        $('div.' + classAC).css({
                            'top': ( height + position.top + 6 ) + 'px',
                            'left': ( position.left )+'px',
                            'margin': '0px'
                        });

                        $('div.' + classAC + ' ul').css({
                            'margin-left': '0px'
                        });

                        $('div.' + classAC + ' li').each(function( n, el )
                        {
                            el = $(el);
                            el.mouseenter(function(){
                                $('div.' + classAC + ' li.' + selClass).removeClass(selClass);
                                $(this).addClass(selClass);
                            });
                            el.find(".caption").click(function()
                            {
                                thisElement.attr('value', el.text());

                                if( typeof( callback ) == "function" )
                                    callback( el.attr(attrCB).split('_') );

                                $('div.' + classAC).remove();
                                thisElement.focus();
                            });

                            el.hover(function(e) {
                                urlText=$("<div>").attr("id","autocomplete_tooltip").addClass("tooltip").html($(this).find("td").attr("uri"));

                                urlText.css({
                                    position:"absolute",
                                    top:(e.pageY+20)+"px",
                                    left:(e.pageX+20)+"px"
                                    });

                                $("body").append(urlText);
                            },function() {
                                $("#autocomplete_tooltip").remove();
                            });


                        }); 
                    }
                });
            }
            if (kc == 38 || kc == 40){
                if ($('div.' + classAC + ' li.' + selClass).length == 0)
                {
                    if (kc == 38)
                    {
                        $($('div.' + classAC + ' li')[$('div.' + classAC + ' li').length - 1]).addClass(selClass);
                    } else {
                        $($('div.' + classAC + ' li')[0]).addClass(selClass);
                    }
                }
                else
                {
                    sel = false;
                    $('div.' + classAC + ' li').each(function(n, el)
                    {
                        el = $(el);
                        if ( !sel && el.hasClass(selClass) )
                        {
                        el.removeClass(selClass);
                        $($('div.' + classAC + ' li')[(kc == 38 ? (n - 1) : (n + 1))]).addClass(selClass);
                        sel = true;
                        }
                    });
                }
            }
            if (thisElement.val() == '') {
                $('div.' + classAC).remove();
                $("#autocomplete_tooltip").remove();
            }
        });
    }
});
  })(jQuery);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小镇女孩 2024-11-10 05:47:08

将执行 ajax 调用的部分拉入函数中,然后 “debounce” 像这样:

var timeout = thisElement.data('timeout');

function debouncedAjax() {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(ajax, 500);
  thisElement.data('timeout', timeout);
}

这样,您就可以在现在调用 ajax 的任何地方调用 debouncedAjax,并且它只会在平静后执行一次调用500 毫秒。根据口味调整超时时间。

Pull the part that does the ajax call into a function, and then "debounce" it like this:

var timeout = thisElement.data('timeout');

function debouncedAjax() {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(ajax, 500);
  thisElement.data('timeout', timeout);
}

That way you'll be able to call debouncedAjax everywhere it now calls ajax and it will only do one call after a lull of 500ms. Adjust the timeout to taste.

蓝眼睛不忧郁 2024-11-10 05:47:08

我最终使用一个全局变量来存储 setTimeout() 并调用 Ajax 函数,每次发生 keyup 时,您都会清除该变量并使用新的 Ajax 调用重置它,如下所示:

$(document).ready(function () {
    // Define the global variable
    $.go = null;
    // Element keyup
    $("#YourElementId").keyup(function() {
        // Clear the global variable with the previous Ajax
        clearTimeout($.go);
        // Set the variable with the current Ajax call
        $.go = setTimeout(function() {
            FunctionThatCallsTheAjax();
        },1000);
    });
});
function FunctionThatCallsTheAjax(){
    // Ajax Stuff Here
}

您可以调整“1000”超时。
这对我来说效果很好。

I ended up using a global variable to store the setTimeout() with a call for the Ajax Function and every time a keyup happens you clear this variable and reset it with the new Ajax call, like this:

$(document).ready(function () {
    // Define the global variable
    $.go = null;
    // Element keyup
    $("#YourElementId").keyup(function() {
        // Clear the global variable with the previous Ajax
        clearTimeout($.go);
        // Set the variable with the current Ajax call
        $.go = setTimeout(function() {
            FunctionThatCallsTheAjax();
        },1000);
    });
});
function FunctionThatCallsTheAjax(){
    // Ajax Stuff Here
}

You can adjust the '1000' timeout.
It's working nice for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文