JQuery实现下拉框搜索用户名

近期在项目中有用到搜索用户的功能,于是自己使用JQuery写了一个在输入框填写名字然后在下拉框中出现相对应的名字

一、思路

在取数据方面刚开始是有两个方案,第一个方案是在页面load的时候直接请求API将所有的用户名信息都取出来然后保存在数组中,然后在搜索时从中取数据。第二个方案是在搜索时根据输入框的信息实时调用API取数据。由于考虑到如果用户量很多的话在load页面请求数据势必会造成一定的影响,所以最后我决定用第二种方案。

那么在输入用户名时调用API我们肯定也要考虑多个方面,比如在输入用户名时,有些人不想输入完整姓名,输入一半就停止不输入怎么办;API在什么时候请求比较合理(如何减少API请求次数);用户名输入错误找不到又如果提醒用户;搜索到用户名,但是用户忘了选择下拉框的值,直接提交输入框中不完整的名字怎么办;


二、代码( jquery + coffeeScript)

1.核心代码块

ownerSearchInput: (e)->
      t = this
      i = 0
      key = e.which
      if $('.input-sm').val().length != 0 && key != 40 && key != 38 && key != 13
        f = _.debounce(t.ajaxSearch , 500)
        f()
      if key == 40 && t.keyselectIdx < $($('#ownerSearchUl').children()).length
        i = t.keyselectIdx
        t.keyselectIdx += 1
      if key == 38 && t.keyselectIdx > 0
        i = t.keyselectIdx
        t.keyselectIdx -= 1
      if t.keyselectIdx > $($('#ownerSearchUl').children()).length
        t.keyselectIdx = 0
      $($('#ownerSearchUl').children()[i]).removeClass('ownerSearchLiActive')
      $($('#ownerSearchUl').children()[t.keyselectIdx]).addClass('ownerSearchLiActive')
      if key == 13
        $('.input-sm').val($($('#ownerSearchUl').children()[t.keyselectIdx]).children('span').text())
        t.shotName = $($('#ownerSearchUl').children()[t.keyselectIdx]).text().split($($('#ownerSearchUl').children()[t.keyselectIdx]).children('span').text())[0]
ajaxSearch: () ->
      t = this
      $.ajax
        url: 'http://xxx.xxx?name=' + $('.input-sm').val()
        type: 'GET'
        dataType: 'json'
        headers:
          "Content-Type": "application/json"
        beforeSend: (xhr) ->
          xhr.setRequestHeader "Authorization",  "Basic " + config.authen
        success: (result, status, xhr)->
          j = 0
          if($('#ownerSearchUl').length>=1)
            $('#ownerSearchUl').empty()
          else
            $('<ul id="ownerSearchUl"></ul>').appendTo($('.ownerSearchResult'))
          $.each result,(cell,i) ->
            if j == 0
              $('<li class="ownerSearchLi ownerSearchLiActive">' + cell + '<span>' + i + '</span>' + '</li>').appendTo($('#ownerSearchUl'))
            else
              $('<li class="ownerSearchLi">' + cell + '<span>' + i + '</span>' + '</li>').appendTo($('#ownerSearchUl'))
            j+=1
          $('#ownerSearchUl').css('display','block')
        error: (request, textStatus, errorThrown) ->
          console.log(request.responseText)
          console.log(textStatus)
          console.log(errorThrown)

代码也不是很完全,但是这部分也是实现这个功能的核心了

首先在输入框输入内容(keydown)时触发onSearchInput事件,如果输入框内容不为空而且不是键盘操作(上下键和enter键)的时候调用ajaxSearch方法,该事件也就是调用API了。大家可以发现我在调用ajaxSearch方法时用到了_.debounce这个函数,在这里我简单讲解一下这个函数

_.debounce:

我们在上面的思路中有提到如何减少API请求次数,因为按照在输入框输入内容就调用API的话,这样就等于每输入一下字符就调用一次API,这显然是很不合理的,所以我们用到了debounce这个函数,在 JavaScript 中, debounce函数所做的事情就是,强制一个函数在某个连续时间段内只执行一次,哪怕它本来会被调用多次。我们希望在用户停止某个操作一段时间之后才执行相应的监听函数,而不是在用户操作的过程当中,浏览器触发多少次事件,就执行多少次监听函数。

这样的一个好处就是我们在一定时间内不断触发ajaxSearch方法时,debounce 总能阻止上一次的事件,这样等于在规定事件内我们就只会调用一次API,大大提高了效率

debounce函数接受两个参数,从上面的例子中可以看出,第一个参数是回调函数fn,第二个参数是规定要延迟的时间delay,当然在例子中我使用的是underscore的_.debounce,这个还支持第三个参数immediate ,表明回调函数是在一个时间区间的最开始执行(immediate 为 true)还是最后执行(immediate 为 false)。不过我也没用到,有兴趣的可以自己去研究一下。这里就不深究 了

言归正传,调用API之后将返回的数据以li的形式显示在输入框下面,这个html和css方面就不说了,然后就是要绑定键盘事件了,比如上下键聚焦在对应的li上(我是在li上面添加Active类说白了就是加个背景色什么的),点击enter键的时候将带有active类的li的值赋给input。

以上就是大致的思路了

还有一些问题比如用户输入错误提交了怎么办,输入不完整怎么办

这其实只要做一些验证都是不难解决的,哈哈哈,这里就不讲了

写得比较粗糙,请见谅


猜你喜欢

转载自blog.csdn.net/sjw1039115768/article/details/80383484