我的自动完成触发次数太多
我在这里使用自动完成功能: 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将执行 ajax 调用的部分拉入函数中,然后 “debounce” 像这样:
这样,您就可以在现在调用
ajax
的任何地方调用debouncedAjax
,并且它只会在平静后执行一次调用500 毫秒。根据口味调整超时时间。Pull the part that does the ajax call into a function, and then "debounce" it like this:
That way you'll be able to call
debouncedAjax
everywhere it now callsajax
and it will only do one call after a lull of 500ms. Adjust the timeout to taste.我最终使用一个全局变量来存储 setTimeout() 并调用 Ajax 函数,每次发生 keyup 时,您都会清除该变量并使用新的 Ajax 调用重置它,如下所示:
您可以调整“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:
You can adjust the '1000' timeout.
It's working nice for me.