在爱课帮http://www.ikebang.com的项目当中,须要新增长一个搜索功能,刚接到这个任务的时候头都大了,之前历来没有作过。可是办法老是想出来的,只好慢慢的作了。javascript
主要技术php
遇到的问题css
效果图以下(背景图为canvas有些失真):
html
开始上代码了前端
css代码以下:java
<input type="text" class=" global-search js-global-serach "placeholder="请输入搜索内容" value="">
<i class="imv2-search search-logo js-search-logo"></i>
<ul class="search-list js-search-list" >
</ul>
主要功能代码以下:jquery
//第一个问题上下键控制
$(document).on("keyup",".js-global-serach",function(e){
//阻止事件的冒泡传播,使光标始终停留在文本区最后面
e.stopPropagation();
//找到下拉列表中的具备cur类的li的数量若是没有的话,返回-1,有的话获取当前具备cur类li相对于同级元素的索引值
var curIndex = $('.js-search-list li.cur').size() > 0 ? $('.js-search-list li.cur').index() : -1;
if(e.keyCode==13){
var item=$.trim($(this).val())
if(item){
bindEventFuns.startSearch(item);
}
}
//上键控制
if(e.keyCode==38){
if(curIndex > 0){
$('.js-search-list li').eq(curIndex - 1).addClass('cur').siblings('li').removeClass('cur');
//没有的话,让列表中的第一个元素选中
}else if(curIndex == -1){
$('.js-search-list li').eq(0).addClass('cur');
}else{
//第一个选中,若是在按上键的时候应该为最后一个选中,此时curIndex的值为0
$('.js-search-list li').eq($('.js-search-list li').size() - 1).addClass('cur').siblings('li').removeClass('cur');
}
var inputVal = $('.js-search-list li.cur').text();
$(this).val(inputVal);
}
//下键控制
if(e.keyCode==40){
if(curIndex == -1){
$('.js-search-list li').eq(0).addClass('cur');
}else if(curIndex < $('.js-search-list li').size() - 1){
$('.js-search-list li').eq(curIndex + 1).addClass('cur').siblings('li').removeClass('cur');
}else{
$('.js-search-list li').eq(0).addClass('cur').siblings('li').removeClass('cur');
}
$(this).val($('.js-search-list li.cur').text());
}
})
第二个问题:es6
$(document).on("mousedown",".js-search-list li",function(e){
var item=$.trim($(this).text())
//被点击的哪项存在,且不为鼠标右键的时候,才会发生跳转
if(item && e.button!=2){
bindEventFuns.startSearch(item);
}
})
原本本身写的时候是用的click事件,可是当触发input框的blur事件被触发的时候,列表就会隐藏了,致使没法点击。在网上看到了一种解释:web
鼠标的click事件能够分为鼠标
按下
按鼠标抬起
ajax
看到这就话是个人脑洞瞬间被打开了,那就用onmousedown
来解决,试验了以后发现很是完美。事件之间的互斥性也解决了,啦啦啦!
然而当我用鼠标右键点击的时候它还能跳转,这个就尴尬了,赶快找了下:
event.button
button 事件属性可返回一个
整数
,指示当事件被触发时哪一个鼠标按键被点击
。
event.button=0|1|2
//0 :表明的为点击鼠标左键
//1 :表明点击的为鼠标中间键
//2 :表明点击的为鼠标右键
到此问题2已经解决了。
最后的问题如何解决频繁的向后台发送请求,首先想到的是使用定时器,可是定时器只是延迟发送了,实际上仍是发送请求了,并无从根本上解决问题。
这时就在网络的中开始查找了,最终找到了一个至关好的方法,那就是利用event.timeStamp
官方文档的解释:
该属性可用于经过获取event.timeStamp代码中两点的值并分析差别来分析事件性能
(这就话话就有点6了,也没作深刻的理解,反正确实有这样的效果)。要简单地肯定事件处理程序中的当前时间,请(new Date).getTime()改成使用。
//定义一个全局变量
var lastTime;
//查找方法以下:
searchShow:function(e){
//获取改变的时间戳
lastTime=e.timeStamp;
var searchContent=$.trim($(this).val());
//为空列表隐藏
if(searchContent==""){
$(".js-search-list").hide();
}
//只有输入内容不为空的话发送请求
else{
setTimeout(function () {
if(lastTime-e.timeStamp==0){
$.ajax({
url:"/search/getsearchword",
data:{
word:searchContent
},
datatype:"json",
method:"get",
success:function(res){
var res=JSON.parse(res);
if(res.result==1){
//若是联想词没有数据的话,什么也不作
console.log(res.data)
if(res.data.length==0){
$(".js-search-list").hide();
return;
}
else{
//es6字符串拼接
var connectList=res.data;
var str=``;
for (var index = 0; index < connectList.length; index++) {
str+=`<li>${connectList[index]}</li>`
}
console.log(str);
$(".js-search-list").html(str);
$(".js-search-list").slideDown("fast");
}
}
}
})}
}, 250);
}
},
//判断用户来源地址
startSearch:function(item){
if(rel_page=="resource"||rel_page=="col_resource"){
window.location.href="/search/resource?words="+item;
return;
}
else if(rel_page=="qa"||rel_page=="answer"||rel_page=="col_question"||rel_page=="bookqa"||rel_page=="bookwaitreply"||rel_page=="lessonqa"||rel_page=="lessonwaitreply"){
window.location.href="/search/qa?words="+item;
return;
}
else if(rel_page=="lesson"||rel_page=="col_lesson"){
window.location.href="/search/lesson?words="+item;
return;
}
else if(rel_page=="designlist"||rel_page=="col_designlist"||rel_page=="design"){
window.location.href="/search/design?words="+item;
return;
}
else{
window.location.href="/search/index?words="+item;
$(".js-search-tool").val(item);
}
}
注意:因为自2004年以来开放的错误,该值在Firefox中未正确填充,所以没法知道在该浏览器中建立事件的时间
jq api 官网:https://api.jquery.com/event.timeStamp/
至此,在开发搜索工程中遇到的问题基本上已经解决了,在这个工做中也学到了不少的东西。最重要的一点就是在写代码以前,必定要把逻辑弄清楚了这样才会事半功倍
。