记录生活中的点滴,分享、学习、创新
实现一个具有级联效果的下拉搜索框,实现的结果如下图所示

我们主要通过这个组件,来学习一些细微的逻辑,比如: 如何计算input框内文字的长度; 如何获取光标的位置;如何实现滚动条随着上下键盘的按动进行移动......
具体需求如下
接下来我们根据需求,来写我们的逻辑
首先我们搭建html页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25  | <input #targetInput autocomplete="off" nz-input [(ngModel)]="searchValue" (keydown)="handlePress($event)" (input)="handleSearchList()"/><div #searchList class="search-popup" [hidden]="!visible" (keyDown)="onKeydown($event)">  <nz-spin [nzSpinning]="searchLoading" [class.spinning-height]="searchLoading">   <div class="data-box" *ngIf="searchData && searchData.length !== 0">    <ul>    // 这里在上篇文章中已经讲解过,如何实现让匹配的文字高亮显示~     <li      id="item"      *ngFor="let item of searchData;let i = index;"      [class.item-selected]="curIndex === i"      (mouseover)='hoverDataItem(i)'      (click)="onSelectClick(item)">      <span [innerHTML]="item | highlightSearchResult:searchValue | safe: 'html'"></span>     </li>    </ul>   </div>  </nz-spin></div> | 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59  | .search-popup { height: 376px; width: 246px; overflow-y: auto; box-shadow: 0 2px 8px rgba(0,0,0,.15); border-radius: 4px; position: absolute; background-color: #fff; z-index: 999; top: 92px; right: 61px; .data-box {  margin: 0 10px;  &:not(:last-child) {   border-bottom: 1px solid #E4E5E7;  }  .no-search-data {   display: inline-block;   width: 100%;   text-align: center;   color: #C3C9D3;   line-height: 40px;  } } & ul {  margin: 0 -10px;  margin-bottom: 0;  text-align: left; } & li {  padding: 3px 10px;  position: relative;  list-style: none;  height: 32px;  line-height: 26px;  &:hover {   cursor: pointer;   background-color: #e6f7ff;  }  &.item-selected {   background-color: #E6F7FF;  } } &.item-selected {  background-color: #E6F7FF; }.hidden-box { display: inline-block; border: 1px solid #ddd; visibility: hidden;} | 
实现相关的逻辑
根据前两个需求,我们需要根据文本框中的”.“进行向后移动,向右移动的最大距离不能超过文本框的宽度。
思路: 我们需要将文本框中的字符串根据”.“来转换成数组,并且要想办法获取文本框中文字的长度。如何获取文本框中文字的长度呢?我们可以将文字的内容,重新放到一个display: inline-block的div容器中,然后获取容器的宽度,如下代码所示~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53  | // html <!-- 用于测量input框的文字宽度 --> 
		*
	 
		
		
		
	 |