zoukankan      html  css  js  c++  java
  • input模拟输入下拉框

        功能点:

        输入、下拉选择、根据输入内容模糊检索、键盘上下键选择

      实现思路:

        显示隐藏:

          input获取焦点显示,失去焦点隐藏

        下拉选择:

          以父元素为基准,通过绝对定位定位至input输入下方

        模糊检索:

          监听输入数据的变化,过滤符合要求的数据

        键盘上下选择:

          监听input的键盘事件,判断keycode值,再触发上下键时,动态计算滚动条滚动的距离

        控制事件触发频率,采用函数节流

      具体实现过程:

        节流函数:

     1 function throttle(func, wait, options) {//函数节流
     2         var context, args, result;
     3         var timeout = null;
     4         var previous = 0;
     5         if (!options) options = {};
     6         var later = function() {
     7             previous = options.leading === false ? 0 : new Date().getTime();
     8             timeout = null;
     9             result = func.apply(context, args);
    10             if (!timeout) context = args = null;
    11         };
    12         return function() {
    13             var now = new Date().getTime();
    14             if (!previous && options.leading === false) previous = now;
    15             var remaining = wait - (now - previous);
    16             context = this;
    17             args = arguments;
    18             if (remaining <= 0 || remaining > wait) {
    19                 if (timeout) {
    20                     clearTimeout(timeout);
    21                     timeout = null;
    22                 }
    23                 previous = now;
    24                 result = func.apply(context, args);
    25                 if (!timeout) context = args = null;
    26             } else if (!timeout && options.trailing !== false) {
    27                 timeout = setTimeout(later, remaining);
    28             }
    29             return result;
    30         }
    31     }

    功能代码:

      1 xxx.directive('inputAndSelect', function ($timeout) {
      2     return {
      3       restrict: 'AE',
      4       replace: true,
      5       require: 'ngModel',
      6       scope: {
      7         'ngModel': '=',
      8         'data': '@',
      9         'callback': '&'
     10       },
     11       template: '<div class="select-box">' +
     12         ' <input type="text" ng-focus="inputOnFocus($event)" ng-blur="inputOnBlur()"' +
     13         '      ng-model="ngModel" style="z-index: 10;" class="form-control huowu-input"><span class="arrow-down" style="display:inline-block; 12px;height: 8px;right: 14px;' +
     14         '   border-left: 6px solid transparent;
    ' +
     15         '    border-right: 6px solid transparent;
    ' +
     16         '    border-top: 8px solid #818181;"></span>' +
     17         '   <div class="select-box-container" style="z-index: 999;background-color: #fff;" ng-show="showSelect">' +
     18         '     <div class="select-box-item" ng-click="selectInputItem(item)" ng-repeat="item in dataList">{{item}}</div></div>' +
     19         '</div>',
     20       link: function(scope, element, attrs) {
     21         //显示/隐藏下拉列表
     22         scope.showSelect = false;
     23         scope.dataList = [];
     24         scope.selectIndex = -1;
     25         var eleInput = element.find('input');
     26         eleInput.attr('id', attrs.id);
     27         //input获取焦点
     28         eleInput.unbind('focus').bind('focus',function() {
     29           scope.showSelect = true;
     30           scope.dataList = JSON.parse(scope.data);
     31           element.find('.select-box-container .select-box-item').removeClass('option-active');
     32           $timeout(function () {
     33             element.find('.select-box-container').scrollTop(0);
     34           }, 0);
     35           if (scope.ngModel) {
     36             scope.dataList = scope.dataList.filter(function(vv) {
     37               return vv.indexOf(scope.ngModel) !== -1;
     38             })
     39           }
     40           if(attrs.callback) {
     41             scope.$parent[attrs.callback]();
     42           }
     43         });
     44         //选择输入项
     45         scope.selectInputItem = function(item) {
     46           scope.ngModel = item;
     47           scope.showSelect = false;
     48         };
     49         
     50         //input失去焦点
     51         scope.inputOnBlur = function() {
     52           $timeout(function() {
     53             scope.selectIndex = -1;
     54             scope.showSelect = false;
     55           }, 200)
     56         };
     57         //监听输入数据的变化
     58         scope.$watch('ngModel', function(newVal) {
     59           if(!scope.data) return;
     60           var items = JSON.parse(scope.data);
     61           if (!newVal && typeof newVal === 'string') {
     62             scope.dataList = items;
     63           } else {
     64             scope.dataList = items.filter(function(vv) {
     65               return vv.indexOf(newVal) !== -1;
     66             })
     67           }
     68         });
     69         //监听键盘按下事件
     70         eleInput.unbind('keydown').bind('keydown', throttle(function(e) {
     71           //keycode 38 up 40 down
     72           var items = element.find('.select-box-container .select-box-item');
     73           var $container = element.find('.select-box-container');
     74           var keycode = e.keyCode;
     75           if (keycode === 40) {
     76             //按键向下
     77             scope.selectIndex++;
     78             scope.selectIndex = scope.selectIndex > scope.dataList.length - 1 ? 0 : scope.selectIndex;
     79           } else if (keycode === 38) {
     80             //按键向上
     81             scope.selectIndex--;
     82             scope.selectIndex = scope.selectIndex < 0 ? scope.dataList.length - 1 : scope.selectIndex;
     83           } else if (keycode === 13) {
     84             if (scope.selectIndex !== -1) {
     85               scope.ngModel = scope.dataList[scope.selectIndex];
     86               scope.showSelect = false;
     87             }
     88             element.find('input').blur();
     89           }else {
     90             return;
     91           }
     92           items.removeClass('option-active');
     93           $(items[scope.selectIndex]).addClass('option-active');
     94           if(scope.selectIndex === 0) {
     95             $container.scrollTop(0);
     96           }
     97           $container.scrollTop(scope.selectIndex*25);
     98         }, 50));
     99       }
    100     }
    101   })

       效果图:

      

  • 相关阅读:
    LOJ6435 「PKUSC2018」星际穿越
    LOJ6433 「PKUSC2018」最大前缀和
    LOJ2541 「PKUWC2018」猎人杀
    LOJ2545 「JXOI2018」守卫
    LOJ2290 「THUWC 2017」随机二分图
    CF1007B Pave the Parallelepiped
    【学习笔记】卡特兰数
    Linux系统命令“su
    免密
    Window操作系统下的SSL证书管理
  • 原文地址:https://www.cnblogs.com/gerry2019/p/10448168.html
Copyright © 2011-2022 走看看