gerry2019

    功能点:

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

  实现思路:

    显示隐藏:

      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;width: 12px;height: 8px;right: 14px;\' +
 14         \'   border-left: 6px solid transparent;\n\' +
 15         \'    border-right: 6px solid transparent;\n\' +
 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   })

   效果图:

  

 

分类:

技术点:

相关文章:

  • 2021-11-21
  • 2021-11-01
  • 2021-12-31
  • 2021-11-01
  • 2021-12-19
  • 2021-10-19
猜你喜欢
  • 2021-11-01
  • 2022-12-23
  • 2022-12-23
  • 2021-08-06
  • 2022-12-23
  • 2021-11-01
  • 2021-11-01
相关资源
相似解决方案