zoukankan      html  css  js  c++  java
  • 实现类似于百度实时搜索将结果在下拉框中显示的功能

    本文主要实现一个类似于百度搜索一样,当在输入框中输入内容实时向后台发送请求,并将返回的内容在输入框下面用下拉框的形式显示出来的功能。

    由于本人是前端程序员,so,这里只介绍前端实现部分,实现分为HTML,JS两部分(后台对接使用的是PHP):

    HTML:

      第一步:封装一个组件用于页面实现

     1 /**
     2      * Print a FilterlistDiv
     3      *
     4      * @param  string $name 表单提交的字段name
     5      * @param  string $value 表单提交的value
     6      * @param  string $searchInputId  输入框id
     7      * @param  string $inputVal  输入框value
     8      * @param  string $filterDivId
     9      * @param  string $class
    10      * @param  string $inputPlaceholder
    11      * @param  string $searchInputName 需要提交的input的name属性
    12      * @access public
    13      * @return string
    14      */
    15      public static function searchFilterInput($name, $value, $searchInputId, $inputVal = '', $class = '', $inputPlaceholder = '', $searchInputName = '')
    16      {
    17         $html = '';
    18         $html .= html::input($name, $value, "class='hidden'");
    19         $html .= html::input($searchInputName, $inputVal, "id='{$searchInputId}' placeholder='{$inputPlaceholder}' class='form-control {$class}'");
    20         $html .= "<div class='inputFilter'></div>";
    21 
    22         return $html;
    23      }

      第二步:页面调用该组件

    1 // 页面调用
    2 echo html::searchFilterInput('trader',  '' ,'traderInput', '', '', , );

    JS部分:

      第一步:通过扩展jQuery的方式将该方法进行封装,主要包含实时请求事件以及键盘操作事件,该方法根据传入的参数来进行不同的处理,主要处理的参数有:1.url:搜索数据的url;2.getAll:用于标示若输入为空时是否显示所有数据(适用于数据列表少的数据,类似于select下拉框);3.canAdd:用于标识当输入的信息搜索不到时是否允许用户将该信息作为新的数据添加进来。在进行实时请求中,使用setTimeout来进行节流,防止向后台请求频率过多。

      1 +function($, window, document, Math)
      2 {
      3     'use strict';
      4 
      5     var searchFilter = function(element, options)
      6     {
      7         this.$            = $(element);
      8         this.options      = this.getOptions(options);
      9         this.$next        = this.$.next();
     10 
     11         this.init();
     12     };
     13 
     14     searchFilter.prototype.getOptions = function (options)
     15     {
     16         options = $.extend({}, searchFilter.DEFAULTS, this.$.data(), options);
     17         return options;
     18     };
     19 
     20     searchFilter.prototype.init = function()
     21     {
     22         //绑定事件
     23         this.bindEvents();
     24     };
     25 
     26     searchFilter.prototype.bindEvents = function()
     27     {
     28         var $this = this.$,
     29             $next = this.$next,
     30             url   = this.options.url,
     31             getAll= this.options.getAll,
     32             cantFindInfo = this.options.cantFindInfo ? this.options.cantFindInfo : '',
     33             canAdd= this.options.canAdd;
     34 
     35         var focus = function(){
     36             if($next.find('ul li').length > 1)
     37             {
     38                 $next.width($this.width()+20);
     39                 $next.show();
     40             }
     41 
     42             // 通过仓库动态加载货位
     43             if($this.attr('id') == 'shelfInput'){
     44                 var store = $this.parents('#selectPosition').find('#store').val();
     45                 url = createLink('store', 'getShelvesBySearch', 'storeId='+store);
     46             }
     47 
     48             $this.unbind('input propertychange');
     49             $this.bind('input propertychange', change);
     50             if(getAll){
     51                 getListByInput($this.val());
     52             }
     53             else if($this.val() !== '' && $next.find("li").length == 0){
     54                 getListByInput($this.val());
     55             }
     56         }
     57 
     58         var blur = function(){
     59             setTimeout(function(){
     60                 $next.hide();
     61                 $this.prev().val('');
     62                 if($this.val() !== '')
     63                 {
     64                     var lis = $next.find("li");
     65                     for(var i = 0; i < lis.length; i++){
     66                         if($this.val() == lis[i].innerText){
     67                             $this.prev().val($(lis[i]).attr('id'));
     68                             break;
     69                         }
     70                     }
     71                     
     72                     if($this.prev().val() == '' && !canAdd){
     73                         $this.val('');
     74                     }
     75                 }
     76             },200);
     77         }
     78 
     79         var change = function(){
     80             if($this.val() != '' || getAll){
     81                 $next.width($this.width()+20);
     82                 $next.show();
     83                 setTimeout(function(){getListByInput($this.val())}, 300);
     84             }
     85         }
     86 
     87         var keydown = function(){
     88             var key       = event.keyCode,
     89                 searchNum = $next.find("li").length, // 搜索到的相关条数
     90                 li        = $next.find("li.active-item"), // 当前通过键盘选中的是第几条li
     91                 index     = $next.find('li').index(li);
     92 
     93             switch(key)
     94             {
     95                 case 13: // 回车键
     96                     event.preventDefault();
     97                     if(li.attr('id')) {
     98                         selectOptionToInput(li.attr('id'), li.text());
     99                     }
    100                     $next.hide();
    101                     break;
    102                 case 38: // 上键
    103                     event.stopPropagation();
    104                     event.preventDefault();
    105                     if(index >= 0)
    106                     {
    107                         index--;
    108                         if (index == -1){
    109                             if(canAdd)  $next.find("li").removeClass('active-item');
    110                             else        index = 0; //到顶了
    111                         }
    112 
    113                         // 使选中的焦点永远能看到
    114                         var $currLi = $next.find("li:eq(" + index + ")"),
    115                             $contanier = $currLi.closest('.inputFilter');
    116 
    117                         if($currLi.position().top <= 20 )
    118                         {
    119                             $contanier.scrollTop($contanier.scrollTop() - $currLi.height());
    120                         }
    121                     }
    122 
    123                     break;
    124                 case 40: // 下键
    125                     event.stopPropagation();
    126                     event.preventDefault();
    127                     $next.show();
    128                     index++;
    129 
    130                     if (index == searchNum) index = searchNum - 1; //到底了
    131 
    132                     // 使选中的焦点永远能看到
    133                     var $currLi = $next.find("li:eq(" + index + ")"),
    134                         $contanier = $currLi.closest('.inputFilter');
    135 
    136                     if(($currLi.position().top + $currLi.height() + 20) > $contanier.height())
    137                     {
    138                         $contanier.scrollTop($contanier.scrollTop() + $currLi.height());
    139                     }
    140 
    141                     break;
    142                 default: break;
    143             }
    144             if(index >= 0){
    145                 li = $next.find("li:eq(" + index + ")");
    146                 li.addClass("active-item").siblings().removeClass('active-item');
    147             }
    148         }
    149 
    150         var getListByInput = function(value)
    151         {
    152             $.ajax({
    153                 type: "POST",
    154                 data: {"value": value},
    155                 url :  url,
    156                 dataType:'json',
    157                 success:function(data){
    158                   var searchList = "<ul>";
    159 
    160                   if(!isEmptyObj(data))
    161                   {
    162                       for(var key in data){
    163                           var li = "<li id='" + key + "'>" + data[key] + "<b></b></li>";
    164                           searchList += li;
    165                       }
    166                   } else {
    167                       searchList += "<li>" + cantFindInfo + "</li>";
    168                   }
    169 
    170                   searchList += "</ul>";
    171 
    172                   // 重新加载下拉列表
    173                   $next.find('ul').remove();
    174                   $next.append(searchList);
    175                   $next.find('li').each(function(i,e){
    176                       $(e).on('click',function(){
    177                           selectOptionToInput($(this).attr('id'), $(this).text());
    178                       });
    179                   });
    180 
    181                   // 若没有显示下拉框则显示下拉框
    182                   if(getAll && $next.find('ul li').length > 1){
    183                     $next.width($this.width()+20);
    184                     $next.show();
    185                   }
    186                   if(!canAdd){
    187                     $next.find("li:eq(0)").addClass('active-item');
    188                   }
    189                 },
    190                 error:function(message){
    191                 }
    192             });
    193         }
    194 
    195         var selectOptionToInput = function(id, name)
    196         {
    197             var $prev = $this.prev();
    198 
    199             $this.val(name);
    200             $prev.val(id);
    201             $prev.change();
    202             $next.find('li#'+id).addClass('active-item').siblings().removeClass('active-item');
    203         }
    204 
    205         this.$.on('focus', focus);
    206         this.$.on('keydown', keydown);
    207         this.$.on('blur', blur);
    208         if($this.is(":focus")){
    209             $this.bind('input propertychange', change);
    210         }
    211     }
    212 
    213     $.fn.searchFilter = function(option)
    214     {
    215         return this.each(function()
    216         {
    217             var $this   = $(this);
    218             var data    = $this.data('zui.searchFilter');
    219             var options = typeof option == 'object' && option;
    220 
    221             if (!data) $this.data('zui.searchFilter', (data = new searchFilter(this, options)));
    222 
    223             if (typeof option == 'string') data[option]();
    224         })
    225     };
    226 
    227     $.fn.searchFilter.Constructor = searchFilter;
    228 }(jQuery,window,document,Math);

      第二步:调用searchFilter方法

    1  $('#traderInput').searchFilter({url: getTraderUrl, cantFindInfo: “无法找到该信息”}); 

      

  • 相关阅读:
    PHP设计模式之适配器模式
    PHP设计模式之注册模式
    PHP中 构造函数(__construct)和析构函数(__destruct)
    PHP中 extends、implements、abstract、interface 的区别
    proxysql
    安装xtrabackup并进行全量备份
    锁解析
    索引与算法
    约束
    show语句
  • 原文地址:https://www.cnblogs.com/hbujt/p/4872707.html
Copyright © 2011-2022 走看看