我有一个使用javascript的自定义自动完成功能,它调用了keyup函数,该函数调用web服务来获取结果。它会生成结果,但是当我在字段中快速输入字符时,每个字符逐渐逐渐输入字符,因此UI上的最终感觉看起来非常慢。是否有任何可能的方法来设置输入延迟所以调用服务的ACCrequestSuggestions函数将在用户进入该字段时进行相当大的暂停时被调用。或者还有其他更好的方法来处理这个使用jvascript。请帮忙。
/**
* Handles keyup events.
*/
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
var iKeyCode = oEvent.keyCode;
//for backspace (8) and delete (46), shows suggestions without typeahead
if (iKeyCode == 8 || iKeyCode == 46) {
ACCrequestSuggestions(this, false);
//make sure not to interfere with non-character keys
} else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
//ignore
} else {
//request suggestions from the suggestion provider with typeahead
ACCrequestSuggestions(this,true);
}
};
/**
* Generate results and create the autocomplete drop down
*/
ACCrequestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/,
bTypeAhead /*:boolean*/) {
var aSuggestions = [];
// suggestions function will invoke service call to generate results based on input
aSuggestions = new Suggestions();
//provide suggestions to the control by building div of results
oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
};
更新:
我按照建议使用了settimeout,效果很好。我打字时感觉更快。我的websetvice数据不是静态数据集。 Web服务根据我输入的字符进行搜索。所以我无法在客户端缓存数据。所以我无能为力。
var timeout; // scope global
if (timeout != "")
{
clearTimeout(timeout);
}
timeout = setTimeout(function(){
//Code to retrieve suggestions
},50);
答案 0 :(得分:1)
您可以使用setTimeout()
创建延迟,并在注册多次击键后只调用ACCrequestSuggestions
一次:
AutoSuggestControl.prototype.handleKeyUp = (function() {
var timer;
return function (oEvent) {
var that = this;
try {
clearTimeout(timer); //stop timeout on key up if it's already running
} catch(ignore) {}
//call your code with a given delay
timer = setTimeout(function() {
/***your original code***/
var iKeyCode = oEvent.keyCode;
//for backspace (8) and delete (46), shows suggestions without typeahead
if (iKeyCode == 8 || iKeyCode == 46) {
ACCrequestSuggestions(that, false);
//make sure not to interfere with non-character keys
} else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
//ignore
} else {
//request suggestions from the suggestion provider with typeahead
ACCrequestSuggestions(that,true);
}
}, 300); //300 ms should be nice for performance and also for user experience
}
})();
当在小于300毫秒的距离内击中多个键时,请注意此版本仅在按下最后一个键时调用ACCrequestSuggestions
。这可能会导致问题,但通常只会向用户显示一个结果,这当然应该是最后一次按键产生的结果。
答案 1 :(得分:0)
你在这里运行了很多代码,许多函数被调用,所有这些函数都可以运行多行代码。
开始的地方是添加一些逻辑并尝试编写代码。
如果可能的话,在做任何事情之前,首先等待2-3个字符条目,因为大多数单词至少需要2-3个字母。
二。使用setTimeout调用来包装执行所有工作的main函数调用,这将创建一个现在释放DOM / UI的线程情况。但它可能无法单独解决问题。
// tmr must have the scope to exist across all your methods
tmr = setTimeout(function(){ACCrequestSuggestions(this,true);},300)
正如我所示,每次键入一个键时,这将重置tmr。这将阻止所有代码运行,直到最后一次按键后300ms。
您可以在重置之前添加一个检查以查看是否已设置tmr,这将使autosuggest在键入时每300毫秒运行一次。
// for the purpose of the example we need a reference to our scope so we can
// use it in the function call below;
var self = this;
if (tmr) return
var tmr = setTimeout(function(){ACCrequestSuggestions(self,true);},300)
然后,当自动建议完成时,需要在代码中将tmr设置为undefined,允许在类型catch事件中触发新的tmr。
tmr=undefied;
我还会好好看看所有代码,并期待加快速度,如果网络服务很好,可以使用正确的策略让它看起来几乎是即时的。
更新:如何加快您的javascript速度!
Stack Overflow上有很多次我看到有关慢速代码的问题。在此示例中,OP正在寻求以用户类型的速度调用Web服务。从一开始就不会很好。
基础是用户输入一个角色时说&#34; A&#34;他打电话给网络服务器并对他的大数据进行一些API搜索,然后发回一大堆数据或一小部分数据。然后,当用户键入&#34; P&#34; - &GT; &#34; AP&#34;他重新做了这件事,尽管他已经掌握了最后一次电话的数据。
首先,当您搜索需要2-3个字母的东西时,要获得有意义的东西,这是第一个加快速度并减少负荷的地方。在2-3之后搜索,这也减少了服务器发回所有数据时的负载。
其次,一旦你在这个例子中找回了数据,我们就不需要再次调用服务器了。搜索可以在javascript中非常容易地完成,因为我们拥有来自A ---&gt;的结果的所有数据。向前。
这些技术可将您的应用/网站的性能提高10倍,并减少服务器的负载,更不用说您的用户和老板的体验了!