直奔主题,google和百度的搜索框都会有这种自动提示关联词条的功能,自己最近接触的项目也有多个地方要做这个功能,后台开发咱不懂,所以从前端JS方面来说说这个功能的主要两点性能优化。
首先这个搜索框如果要触发自动提示的词条,肯定是每次keyup(咱们老大说keyup事件在某些浏览器里有问题,建议用keydown,但是我没发现问题,而且我觉得keyup后触发在某些情景下比keydown下要好,所以我用的keyup)事件后根据现在input里的value值来遍历相关联词条.
所以每次keyup后得到input里的value值,都需要根据value值请求后台来返回相关词条的内容,这里的ajax请求是用jsonp来做的,开发那边给到我一个地址格式,大概是这样:
http://xxx.com/xxx/xxx?Jsoncallback=jQuery17109596129641868174_1387338048392&keyword=1
两个关键的地方就是Jasoncallback和keyword,Jasoncallback是jsonp的格式,然后keyword后面跟的就是搜索的关键字,ajax代码大概是这样:
$.ajax({
type: "get",
url: 'http://xxx.com/xxx/xxx?',
dataType: "jsonp",
data:"Keyword=" + encodeURIComponent(inputvalue),
jsonp: "Jsoncallback",
jsonpCallback:"askTag",//任意值,即jasoncallback后的值
success: function (data) {
//显示自动提示框,给框里填关联词条的内容
},
error: function () {
//alert('返回失败!');
}
});
好了,到这里这个功能就做好了,用户在每次keyup之后都会调用ajax来请求后台数据然后显示关联词条。
现在说下JS优化部分,当你做到刚才说的那些之后,你会发现你每输入一个字母都会调用一次ajax,这样的ajax调用太频繁了而且没有必要,拿最流行的搜狗拼音输入法来说,你每输入一个字母,都已经是给input赋值了,这样都会调用一次ajax,但是这时候的拼音所关联的内容基本上不会是你想要的,你想要的只是打出来的汉字所关联的内容。
## 1、ajax调用做下延迟执行
我们肯定做不到根据输入内容来判断是否执行ajax关联,但是我们可以**对ajax调用做下延迟执行**。这样当用户输入内容时,如果两次按键的间隔时间过小(我认为大概在200毫秒,可以根据自己的服务器速度和用户体验来调整这个时间),就可以当做他是在继续输入他想要的内容,这时候没有必要来显示关联内容。代码如下:
var timeout = 0;
$('input').keyup(function(){
clearTimeout(timeout);
timeout = setTimeout(function(){
$.ajax({
});
},200);
});
好了,这样就可以有效的减少没必要的ajax请求了。
## 2、ajax请求到的内容作缓存
**第二点优化是给ajax请求到的内容作缓存**,大概意思就是说,你输入了“上海”,这时候做了一次ajax请求,然后你继续输“上海东方明珠”,这时候又有一次ajax请求,然后你把“东方明珠”删掉了,这时候input里的值是“上海”,前面已经请求过一次“上海”的ajax请求了,现在又要重复请求一次关键字是“上海”的ajax请求。
这样的话就有点浪费,所以我们可以把每次ajax请求的关键字和请求得到的内容先存到一个变量a中去,然后每次keyup后先判断变量a里有没有这个关键字所请求到的内容,如果有,就读取现有的内容,如果没有再请求ajax,这样又可以有效的减少ajax请求数了。
代码如下:
var timeout = 0;
var ajaxCache = {};//定义缓存对象
$('input').keyup(function(){
var inputValue = $(this).val();
clearTimeout(timeout);
timeout = setTimeout(function(){
if(!!ajaxCache[inputValue]){
//显示自动提示框,给框里填关联词条的内容
}else{
$.ajax({
success:function(data){
//显示自动提示框,给框里填关联词条的内容
ajaxCache[inputValue]=[];
ajaxCache[inputValue]=data;//给缓存对象赋值
}
});
}
},200);
});
总结一下两点优化就是给ajax做延迟并给ajax做缓存,有效减少ajax请求来优化前端性能。如有其他优化建议欢迎留言讨论~~