搜索功能的实现

在爱课帮http://www.ikebang.com的项目当中,需要新增加一个搜索功能,刚接到这个任务的时候头都大了,以前从来没有做过。但是办法总是想出来的,只好慢慢的做了。

主要技术

  1. 前端:jQuery、seajs
  2. 后台:php

遇到的问题

  1. 通过上下键来选择列表内容
  2. 失焦(列表会隐藏)如何在点击列表中的每一项
  3. 如何避免频繁的向后台请求数据(减少后台的压力)

效果图如下(背景图为canvas有些失真):
这里写图片描述

开始上代码了

css代码如下:

<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>

主要功能代码如下:

//第一个问题上下键控制
 $(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());
            }
        })

第二个问题:

$(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事件被触发的时候,列表就会隐藏了,导致无法点击。在网上看到了一种解释:

鼠标的click事件可以分为鼠标按下按鼠标抬起

看到这就话是我的脑洞瞬间被打开了,那就用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/

至此,在开发搜索工程中遇到的问题基本上已经解决了,在这个工作中也学到了很多的东西。最重要的一点就是在写代码之前,一定要把逻辑弄清楚了这样才会事半功倍

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值