zoukankan      html  css  js  c++  java
  • 基于AngularJs的联想搜索框组件封装

    组件组成:HTML模板 + JS文件

    组件原理:HTML模板就是规定组件由哪些元素构成,这些元素是什么结构的,既组件是长啥样的;JS文件是用来声明和定义组件功能的,相当于JSP文件中<script>标签中JS代码的功能;

    联想搜索:用户在输入框中输入关键字,并自动向后端发送异步请求,得到请求回来的数据后,以列表的形式展示在搜索框下方,用户通过鼠标悬停或者上下键选择选项,鼠标点击或者Enter键实现搜索并列表消失的功能,功能如下图:

    代码部分

    • HTML模板:
    1 <span class="relative">
    2     <input type="text" placeholder="请输入关键字..." ng-model="inputModel" ng-change="method.timeflash()" ng-blur="method.closeSearch()" ng-focus="method.searchData()" ng-keydown="method.keyDownEvent($event)">
    3     <i class="iconfont searchBtn"></i>
    4     <span class="search-list" ng-show="vm.dataList.length > 0" id="forhide">
    5         <a href="javascript:void(0)" ng-repeat="data in vm.dataList | limitTo:10"
    6            ng-mouseover="method.mouseOverEvent($index)" ng-click="method.enterKeyEvent(data)">{{data.value}}</a>
    7     </span>
    8 </span>

    注解:输入框对象$scope.inputModel用于保存输入的关键字,输入框提供change、blur、focus、keydown事件的监听。

      change事件:当输入框内容变化时,触发计时器,400毫秒后开始搜索;

      blur事件:搜索框失焦时,清空并隐藏数据列表;

      focus事件:输入框获得焦点时,直接搜索;

      keydown事件:按键监听事件,监听上下键及Enter事件,上下键选择列表中的数据项,Enter键做用户指定操作。

    • CSS类:
     1 .relative{position: relative!important;}
     2 .absolute{position: absolute!important;}
     3 
     4 .search-list {
     5     position: relative;
     6     width: 100%;
     9     background: #fff;
    10     border: solid 1px #5093e1;
    11     z-index: 10;
    12 }
    13 
    14 .search-list a {
    15     width: 100%;
    16     height: 30px;
    17     line-height: 30px;
    18     float: left;
    19     color: #666;
    20     display: block;
    21     font-size: 13px;
    22     padding: 0 10px;
    23     text-decoration: none;
    24 }
    25 
    26 .search-list a:hover {
    27     color: #666;
    28 }
    29 
    30 .search-list .selected {
    31     background: #5093e1;
    32     color: #fff!important;
    33 }

    注解:数据列表相对于搜索框相对布局。

    • JS文件
      1 APP.directive('search', ['Postman','$timeout', function (Postman,$timeout) {
      2     return {
      3         scope: {// 传入的参数
      4             inputModel: '=',// 输入框对象
      5             enterKeyEvent: '='// 用户指定操作
      6         },
      7         restrict: 'E',// 封装成Element(元素)类型
      8         templateUrl: 'directive/search/search.html',// 模板路径
      9         replace: false,
     10         link: function ($scope) {
     11             var timer;
     12             var selectListIndex;// 数据列表索引
     13             $scope.vm = {};// 模板视图对象
     14             $scope.method = {};// 模板方法对象
     15 
     16             function initParams(){// 初始化参数
     17                 $scope.vm = {
     18                     selectedData: {},// 选中数据对线
     19                     dataList: []// 数据列表
     20                 };
     21                 $scope.method.enterKeyEvent = $scope.enterKeyEvent;//将传过来的用户指定的方法赋值给组件
     22             }
     23 
     24             function init() {// 程序初始化执行部分
     25                 initParams();
     26             }
     27 
     28             $scope.method.searchData = function () { // 根据关键字搜索联想词
     29                 if ($scope.inputModel === undefined) {// 为空时不做搜索
     30                     return;
     31                 }
     32                 if ($scope.inputModel.length > 0) {// 非空时异步请求联想词
     33                     var promise = Postman.httpGet('data/fuzzy', {// Postman为自己封装的Http请求服务,这里用Get方法请求数据
     34                         keyWord: $scope.inputModel});
     37                     promise.then(function (data) {
     38                         if (data && data.code === 0) {
     39                             $scope.vm.dataList = data.data;// 请求回来的数据赋值给视图对象中的dataList数组
     40                             selectListIndex = -1;// 索引置为-1,不选中任何项
     41                             $('#forhide').show();// 显示列表
     42                         }
     43                     });
     44                 }
     45             };
     46 
     47             $scope.method.keyDownEvent = function ($event) {
     48                 $event.stopPropagation();// 阻止其他按键事件冒泡
     49                 var listArry = $('#forhide>a');
     50                 switch ($event.keyCode) {
     51                     case 38:// 'UP'
     52                         selectListIndex--;
     53                         if (selectListIndex >= 0 && selectListIndex < listArry.length) {
     54                             for (var i = 0; i < listArry.length; i++) {
     55                                 listArry.eq(i).removeClass('selected');// 清除选中样式
     56                                 if (i === selectListIndex) {
     57                                     listArry.eq(i).addClass('selected');// 添加选中样式
     58                                     $scope.inputModel = listArry.eq(i).text();// 将选中项的文本赋值给输入框
     59                                 }
     60                             }
     61                         } else if (selectListIndex < 0) {// 第0项跳转到最后一项
     62                             selectListIndex = listArry.length - 1;
     63                             listArry.eq(0).removeClass('selected');
     64                             listArry.eq(selectListIndex).addClass('selected');
     65                             $scope.inputModel = listArry.eq(selectListIndex).text();
     66                         }
     67                         break;
     68                     case 40:// 'Down'
     69                         selectListIndex++;
     70                         if (selectListIndex >= 0 && selectListIndex < listArry.length) {
     71                             for (var i = 0; i < listArry.length; i++) {
     72                                 listArry.eq(i).removeClass('selected');
     73                                 if (i === selectListIndex) {
     74                                     listArry.eq(i).addClass('selected');
     75                                     $scope.inputModel = listArry.eq(i).text();
     76                                 }
     77                             }
     78                         } else if (selectListIndex >= listArry.length) {// 最后一项跳转到第0项
     79                             selectListIndex = 0;
     80                             listArry.eq(listArry.length - 1).removeClass('selected');
     81                             listArry.eq(selectListIndex).addClass('selected');
     82                             $scope.inputModel = listArry.eq(selectListIndex).text();
     83                         }
     84                         break;
     85                     case 13:// Enter键触发用户指定操作
     86                         $scope.method.enterKeyEvent($scope.vm.dataList[selectListIndex]);
     87                         $scope.method.closeSearch();// 关闭联想词列表
     88                         break;
     89                 }
     90             };
     91 
     92             $scope.method.mouseOverEvent = function (index) {// 鼠标悬停事件:获取悬停数据项的索引,并添加选中样式
     93                 selectListIndex = index;
     94                 var listArry = $('#forhide>a');
     95                 for (var i = 0; i < listArry.length; i++) {
     96                     listArry.eq(i).removeClass('selected');
     97                     if (i === selectListIndex) {
     98                         listArry.eq(i).addClass('selected');
     99                         $scope.inputModel = listArry.eq(i).text();
    100                     }
    101                 }
    102             };
    103 
    104             $scope.method.timeflash = function () {// 定时器控制,400ms后才发送请求
    105                 $timeout.cancel(timer);// 关闭400ms内的上一个计时器,400ms后认为用户停止输入,即输入完成,开始搜索,从而减少多余的请求次数
    106                 timer = $timeout(function () {
    107                     $scope.method.searchData();// 发送搜索请求
    108                 }, 400);
    109             };
    110 
    111             $scope.method.closeSearch = function () {// 关闭联想词列表
    112                 $scope.vm.dataList = [];
    113                 $('#forhide').hide();
    114             };
    115 
    116             init();// 程序入口
    122 } 123 }; 124 }]);
    • 使用样例:
    1 <search input-model="inputBox" enter-key-event="search"></search>

    传递组件需要的两个参数:inputModel和enterKeyEvent。"search"为用户指定的操作、方法。

  • 相关阅读:
    Python自动截图html页面
    filebeat+kafka+logstash+Elasticsearch+Kibana日志收集系统搭建
    k8s重要概念
    1721. 使括号有效的最少添加
    167. 链表求和
    272. 爬楼梯 II
    1609. 链表的中间结点
    SQL server查看触发器是否被禁用
    C#窗体内控件大小随窗体等比例变化
    微信接口返回码参考表
  • 原文地址:https://www.cnblogs.com/hjx-blog/p/6597681.html
Copyright © 2011-2022 走看看