基於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"為用戶指定的操作、方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM