ios实现搜索关键字高亮效果

一. 需求要求实现的效果

汉字支持汉字直接搜索、拼音全拼搜索、拼音简拼搜索

搜索匹配到的关键字高亮显示

搜索结果优先显示全部匹配、其次是拼音全拼匹配、拼音简拼匹配;关键字在结果字符串中位置越靠前,优先显示

支持搜索英文、汉字、电话号码及混合搜索

二. 需求分析

英文名称及电话号码的搜索直接使用完全匹配的方式即可

重难点是汉字的拼音相关的拼音全拼、简拼搜索,比如 “刘亦菲” 对应的搜索关键字有且只有以下三大类总计 25 种匹配汉字:“刘”、“亦”、“菲”、“刘亦”、“亦菲”、“刘亦菲”

简拼相关:"l"、"y"、"f"、"ly"、"yf"、"lyf"

全拼相关:"li"、"liu"、"liuy"、"liuyi"、"liuyif"、"liuyife"、"liuyifei"、"yi"、"yif"、"yife"、"yifei"、"fe"、"fei"

拼音的重难点还包括:比如搜索关键字为“xian”,既要匹配出“先”,也要匹配出“西安”

三. 代码设计

1. 整体流程

首先初始化原始的数据(包含汉语、英文、数字及随意组合),主要是将一个汉语字符串转化为汉语全拼拼音及每个拼音字母所对应汉字的位置 和 汉语简拼拼音和每个拼音字母对应汉字的位置,将初始化之后的信息缓存起来

+ (instancetype)personWithName:(NSString *)name hanyuPinyinOutputFormat:(HanyuPinyinOutputFormat *)pinyinFormat {
 WPFPerson *person = [[WPFPerson alloc] init];

 /** 将汉字转化为拼音的类方法
  * name : 需要转换的汉字
  * pinyinFormat : 拼音的格式化器
  * @"" : seperator 分隔符
  */
 NSString *completeSpelling = [PinyinHelper toHanyuPinyinStringWithNSString:name withHanyuPinyinOutputFormat:pinyinFormat withNSString:@""];

 // 首字母所组成的字符串
 NSString *initialString = @"";
 // 全拼拼音数组
 NSMutableArray *completeSpellingArray = [[NSMutableArray alloc] init];
 // 拼音首字母的位置数组
 NSMutableArray *pinyinFirstLetterLocationArray = [[NSMutableArray alloc] init];

 // 遍历每一个字符
 for (NSInteger x =0; x
根据 UISearchResultsUpdating 代理方法 - (void)updateSearchResultsForSearchController:(UISearchController *)searchController 来实时获取输入的最新关键字,并遍历数据源,将匹配到的结果显示出来
// 更新搜索结果
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
 NSLog(@"%@", searchController.searchBar.text);

 [self.searchResultVC.resultDataSource removeAllObjects];

 for (WPFPerson *person in self.dataSource) {
  WPFSearchResultModel *resultModel = [WPFPinYinTools
            searchEffectiveResultWithSearchString:searchController.searchBar.text.lowercaseString
            nameString:person.name
            completeSpelling:person.completeSpelling
            initialString:person.initialString
            pinyinLocationString:person.pinyinLocationString
            initialLocationString:person.initialLocationString];

  if (resultModel.highlightRang.length) {
   person.highlightLoaction = resultModel.highlightRang.location;
   person.textRange = resultModel.highlightRang;
   person.matchType = resultModel.matchType;
   [self.searchResultVC.resultDataSource addObject:person];
  }
 };
 // 将匹配结果按照产品规则进行排序
 [self.searchResultVC.resultDataSource sortUsingDescriptors:[WPFPinYinTools sortingRules]];
 // 刷新tableView
 dispatch_async(dispatch_get_main_queue(), ^{
  [self.searchResultVC.tableView reloadData];
 });
}

匹配的过程是一个重难点,分别进行汉字直接匹配、拼音全拼匹配、拼音简拼匹配

+ (WPFSearchResultModel *)searchEffectiveResultWithSearchString:(NSString *)searchStrLower
              nameString:(NSString *)nameStrLower
            completeSpelling:(NSString *)completeSpelling
             initialString:(NSString *)initialString
           pinyinLocationString:(NSString *)pinyinLocationString
           initialLocationString:(NSString *)initialLocationString {

 WPFSearchResultModel *searchModel = [[WPFSearchResultModel alloc] init];

 NSArray *completeSpellingArray = [pinyinLocationString componentsSeparatedByString:@","];
 NSArray *pinyinFirstLetterLocationArray = [initialLocationString componentsSeparatedByString:@","];

 // 完全中文匹配范围
 NSRange chineseRange = [nameStrLower rangeOfString:searchStrLower];
 // 拼音全拼匹配范围
 NSRange complateRange = [completeSpelling rangeOfString:searchStrLower];
 // 拼音首字母匹配范围
 NSRange initialRange = [initialString rangeOfString:searchStrLower];

 // 汉字直接匹配
 if (chineseRange.length!=0) {
  searchModel.highlightedRange = chineseRange;
  searchModel.matchType = MatchTypeChinese;
  return searchModel;
 }

 NSRange highlightedRange = NSMakeRange(0, 0);

 // MARK: 拼音全拼匹配
 if (complateRange.length != 0) {
  if (complateRange.location == 0) {
   // 拼音首字母匹配从0开始,即搜索的关键字与该数据源第一个汉字匹配到,所以高亮范围从0开始
   highlightedRange = NSMakeRange(0, [completeSpellingArray[complateRange.length-1] integerValue] +1);

  } else {
   /** 如果该拼音字符是一个汉字的首个字符,如搜索“g”,
    * 就要匹配出“gai”、“ge”等“g”开头的拼音对应的字符,
    * 而不应该匹配到“wang”、“feng”等非”g“开头的拼音对应的字符
    */
   NSInteger currentLocation = [completeSpellingArray[complateRange.location] integerValue];
   NSInteger lastLocation = [completeSpellingArray[complateRange.location-1] integerValue];
   if (currentLocation != lastLocation) {
    // 高亮范围从匹配到的第一个关键字开始
    highlightedRange = NSMakeRange(currentLocation, [completeSpellingArray[complateRange.length+complateRange.location -1] integerValue] - currentLocation +1);
   }
  }
  searchModel.highlightedRange = highlightedRange;
  searchModel.matchType = MatchTypeComplate;
  if (highlightedRange.length!=0) {
   return searchModel;
  }
 }
 // MARK: 拼音首字母匹配
 if (initialRange.length!=0) {
  NSInteger currentLocation = [pinyinFirstLetterLocationArray[initialRange.location] integerValue];
  NSInteger highlightedLength;
  if (initialRange.location ==0) {
   highlightedLength = [pinyinFirstLetterLocationArray[initialRange.length-1] integerValue]-currentLocation +1;
   // 拼音首字母匹配从0开始,即搜索的关键字与该数据源第一个汉字匹配到,所以高亮范围从0开始
   highlightedRange = NSMakeRange(0, highlightedLength);
  } else {
   highlightedLength = [pinyinFirstLetterLocationArray[initialRange.length+initialRange.location-1] integerValue]-currentLocation +1;
   // 高亮范围从匹配到的第一个关键字开始
   highlightedRange = NSMakeRange(currentLocation, highlightedLength);
  }
  searchModel.highlightedRange = highlightedRange;
  searchModel.matchType = MatchTypeInitial;
  if (highlightedRange.length!=0) {
   return searchModel;
  }
 }
 searchModel.highlightedRange = NSMakeRange(0, 0);
 searchModel.matchType = NSIntegerMax;
 return searchModel;
}

2. 第三方依赖

首先筛选出一个比较全的第三方库 PinYin4Objc用于汉语转拼音,拼音的 unicode 库比较全,一些新的汉字也都能转成拼音
但是由于该库好久没有更新,获取拼音文件部分代码不适合组件化的直接开发,因此我直接合到源文件里面了
汉语转拼音的格式

// 获取格式化器
+ (HanyuPinyinOutputFormat *)getOutputFormat {
 HanyuPinyinOutputFormat *pinyinFormat = [[HanyuPinyinOutputFormat alloc] init];
 /** 设置大小写
  * CaseTypeLowercase : 小写
  * CaseTypeUppercase : 大写
  */
 [pinyinFormat setCaseType:CaseTypeLowercase];
 /** 声调格式 :如 王鹏飞
  * ToneTypeWithToneNumber : 用数字表示声调 wang2 peng2 fei1
  * ToneTypeWithoutTone : 无声调表示 wang peng fei
  * ToneTypeWithToneMark : 用字符表示声调 wáng péng fēi
  */
 [pinyinFormat setToneType:ToneTypeWithoutTone];
 /** 设置特殊拼音ü的显示格式:
  * VCharTypeWithUAndColon : 以U和一个冒号表示该拼音,例如:lu:
  * VCharTypeWithV   : 以V表示该字符,例如:lv
  * VCharTypeWithUUnicode : 以ü表示
  */
 [pinyinFormat setVCharType:VCharTypeWithV];
 return pinyinFormat;
}

3. 其他细节

排序规则

+ (NSArray *)sortingRules {
 // 按照 matchType 顺序排列,即优先展示 中文,其次是全拼匹配,最后是拼音首字母匹配
 NSSortDescriptor *desType = [NSSortDescriptor sortDescriptorWithKey:@"matchType" ascending:YES];
 // 优先显示 高亮位置索引靠前的搜索结果
 NSSortDescriptor *desLocation = [NSSortDescriptor sortDescriptorWithKey:@"highlightLoaction" ascending:YES];
 return @[desType,desLocation];
}

四. 循环方法测试及优化选择过程

在优化遍历方法的过程中,测试了几种遍历方法,这里以输入关键字“wang”为测试数据,测试真机机型为iPhone SE 10.3

常规 for 循环

/**
 2017-12-06 12:02:51.943006 HighlightedSearch[4459:1871193] w
 2017-12-06 12:02:51.943431 HighlightedSearch[4459:1871193] 开始匹配,开始时间:2017-12-06 04:02:51 +0000
 2017-12-06 12:02:51.980588 HighlightedSearch[4459:1871193] 匹配结束,结束时间:2017-12-06 04:02:51 +0000,耗时:0.0372
 2017-12-06 12:02:52.284488 HighlightedSearch[4459:1871193] wa
 2017-12-06 12:02:52.284771 HighlightedSearch[4459:1871193] 开始匹配,开始时间:2017-12-06 04:02:52 +0000
 2017-12-06 12:02:52.316536 HighlightedSearch[4459:1871193] 匹配结束,结束时间:2017-12-06 04:02:52 +0000,耗时:0.0318
 2017-12-06 12:02:52.516826 HighlightedSearch[4459:1871193] wan
 2017-12-06 12:02:52.517121 HighlightedSearch[4459:1871193] 开始匹配,开始时间:2017-12-06 04:02:52 +0000
 2017-12-06 12:02:52.545542 HighlightedSearch[4459:1871193] 匹配结束,结束时间:2017-12-06 04:02:52 +0000,耗时:0.0285
 2017-12-06 12:02:52.838220 HighlightedSearch[4459:1871193] wang
 2017-12-06 12:02:52.838602 HighlightedSearch[4459:1871193] 开始匹配,开始时间:2017-12-06 04:02:52 +0000
 2017-12-06 12:02:52.880200 HighlightedSearch[4459:1871193] 匹配结束,结束时间:2017-12-06 04:02:52 +0000,耗时:0.0417
 */
for (NSInteger i = 0; i < self.dataSource.count; i++) {

GCD 多线程循环

/**
 2017-12-06 11:56:55.565738 HighlightedSearch[4419:1869486] w
 2017-12-06 11:56:55.566287 HighlightedSearch[4419:1869486] 开始匹配,开始时间:2017-12-06 03:56:55 +0000
 2017-12-06 11:56:55.626184 HighlightedSearch[4419:1869486] 匹配结束,结束时间:2017-12-06 03:56:55 +0000,耗时:0.0601
 2017-12-06 11:56:55.937535 HighlightedSearch[4419:1869486] wa
 2017-12-06 11:56:55.937842 HighlightedSearch[4419:1869486] 开始匹配,开始时间:2017-12-06 03:56:55 +0000
 2017-12-06 11:56:55.983074 HighlightedSearch[4419:1869486] 匹配结束,结束时间:2017-12-06 03:56:55 +0000,耗时:0.0452
 2017-12-06 11:56:56.344808 HighlightedSearch[4419:1869486] wan
 2017-12-06 11:56:56.347350 HighlightedSearch[4419:1869486] 开始匹配,开始时间:2017-12-06 03:56:56 +0000
 2017-12-06 11:56:56.414215 HighlightedSearch[4419:1869486] 匹配结束,结束时间:2017-12-06 03:56:56 +0000,耗时:0.0690
 2017-12-06 11:56:56.711174 HighlightedSearch[4419:1869486] wang
 2017-12-06 11:56:56.712013 HighlightedSearch[4419:1869486] 开始匹配,开始时间:2017-12-06 03:56:56 +0000
 2017-12-06 11:56:56.774761 HighlightedSearch[4419:1869486] 匹配结束,结束时间:2017-12-06 03:56:56 +0000,耗时:0.0632
 */
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(self.dataSource.count, queue, ^(size_t index) {

enumerateObjectsWithOptions 多线程循环

/**
 2017-12-06 11:58:12.716606 HighlightedSearch[4428:1869917] w
 2017-12-06 11:58:12.717005 HighlightedSearch[4428:1869917] 开始匹配,开始时间:2017-12-06 03:58:12 +0000
 2017-12-06 11:58:12.780168 HighlightedSearch[4428:1869917] 匹配结束,结束时间:2017-12-06 03:58:12 +0000,耗时:0.0633
 2017-12-06 11:58:13.058590 HighlightedSearch[4428:1869917] wa
 2017-12-06 11:58:13.058841 HighlightedSearch[4428:1869917] 开始匹配,开始时间:2017-12-06 03:58:13 +0000
 2017-12-06 11:58:13.116964 HighlightedSearch[4428:1869917] 匹配结束,结束时间:2017-12-06 03:58:13 +0000,耗时:0.0581
 2017-12-06 11:58:13.397052 HighlightedSearch[4428:1869917] wan
 2017-12-06 11:58:13.397338 HighlightedSearch[4428:1869917] 开始匹配,开始时间:2017-12-06 03:58:13 +0000
 2017-12-06 11:58:13.460298 HighlightedSearch[4428:1869917] 匹配结束,结束时间:2017-12-06 03:58:13 +0000,耗时:0.0630
 2017-12-06 11:58:13.763888 HighlightedSearch[4428:1869917] wang
 2017-12-06 11:58:13.764263 HighlightedSearch[4428:1869917] 开始匹配,开始时间:2017-12-06 03:58:13 +0000
 2017-12-06 11:58:13.833888 HighlightedSearch[4428:1869917] 匹配结束,结束时间:2017-12-06 03:58:13 +0000,耗时:0.0697
 */
dispatch_queue_t queue = dispatch_queue_create("wpf.updateSearchResults.test", DISPATCH_QUEUE_SERIAL);
[self.dataSource enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

forin 循环

/**
 2017-12-06 12:00:38.217187 HighlightedSearch[4439:1870645] w
 2017-12-06 12:00:38.217575 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:38 +0000
 2017-12-06 12:00:38.253997 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:38 +0000,耗时:0.0364
 2017-12-06 12:00:38.616430 HighlightedSearch[4439:1870645] wa
 2017-12-06 12:00:38.616807 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:38 +0000
 2017-12-06 12:00:38.654969 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:38 +0000,耗时:0.0383
 2017-12-06 12:00:38.948700 HighlightedSearch[4439:1870645] wan
 2017-12-06 12:00:38.949453 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:38 +0000
 2017-12-06 12:00:38.986892 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:38 +0000,耗时:0.0378
 2017-12-06 12:00:39.280979 HighlightedSearch[4439:1870645] wang
 2017-12-06 12:00:39.281563 HighlightedSearch[4439:1870645] 开始匹配,开始时间:2017-12-06 04:00:39 +0000
 2017-12-06 12:00:39.317743 HighlightedSearch[4439:1870645] 匹配结束,结束时间:2017-12-06 04:00:39 +0000,耗时:0.0365
 */
for (WPFPerson *person in self.dataSource) {

最终选择的是forin循环,因为一般情况下 enumerateObjectsWithOptions 多线程是最快的,并且稍快于 dispatch_apply 方法,但是因为这个方法需要操作数组,因此必须将操作数据的那行代码加锁或者在指定线程进行,进行这个操作后效率反而不如其他单线程循环,考虑到搜索结果本来还要再次根据规则排序,就选择了 forin 循环

五. 为什么没有选择hash

首先最重要的一条是当前循环的方式也能满足需求(线上大概四千多条数据,使用过程中基本实时展现)

上文在需求分析中已举例,一个三个字的汉字对应的key值就有20多个甚至更多,在解析过程中是十分耗时的,但需求往往还存在类似微信的“群名称”匹配,每多一个字,对应的key值就多几个数量级

MapTable在高并发情况下,需要不断进行Resize(扩容 & Rehash),并且在Rehash 并发的情况下还可能形成链表环有个优化的思路,考虑到遍历的方式解析快,搜索匹配慢;hash的方式解析慢,搜索匹配快

通过遍历的方式先快速解析数据,此时搜索使用遍历的方式

然后再用hash的方式再次解析数据(考虑到hash表的扩容会使得瞬时效率的降低,为了避免频繁的扩容,先使用桶排序的方法将10个数字、26个英文字母、以及特殊符号开头的key分别放在37个字典里面,整体是一个数组。每个字典里面存放对应key和value),解析完成之后做个标记就采用hash的方式直接使用输入的key值去查询

配合DB缓存,效果应该是很棒的

六. 多音字

简单测了一下拥有该功能的产品:

微信搜索(就是文中讲的该类型搜索)是在本地做的,不支持多音字

钉钉的搜索是服务器做的,支持多音字(但是简单测了一下一些基本的多音字存在bug)

七. 实际项目还要做哪些工作?

正常情况下不会将所有的匹配结果在第一时间全部显示,一般产品需求显示三五个即可,因此可以匹配出若干个结果后停止循环,点击更多再匹配剩余数据源

配合DB和hashTable,每次只解析新增的数据源,解析一次后就缓存起来

八. 使用方法

1. 事例工程

git clone git@github.com:PengfeiWang666/HighlightedSearch.git
cd Example
open HighlightedSearch.xcworkspace

2. Install

pod "HighlightedSearch"

3. Usage

// WPFPinYinDataManager 依次添加数据源(标识符为了防止重名现象)
+ (void)addInitializeString:(NSString *)string identifer:(NSString *)identifier
// 更新搜索结果
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
 ...
 ...
 for (WPFPerson *person in [WPFPinYinDataManager getInitializedDataSource]) {
  WPFSearchResultModel *resultModel = [WPFPinYinTools searchEffectiveResultWithSearchString:keyWord Person:person];
  if (resultModel.highlightedRange.length) {
   person.highlightLoaction = resultModel.highlightedRange.location;
   person.textRange = resultModel.highlightedRange;
   person.matchType = resultModel.matchType;
    [resultDataSource addObject:person];
  }
}

最后附上源码:https://github.com/PengfeiWang666/HighlightedSearch

(0)

相关推荐

  • ios实现搜索关键字高亮效果

    一. 需求要求实现的效果 汉字支持汉字直接搜索.拼音全拼搜索.拼音简拼搜索 搜索匹配到的关键字高亮显示 搜索结果优先显示全部匹配.其次是拼音全拼匹配.拼音简拼匹配:关键字在结果字符串中位置越靠前,优先显示 支持搜索英文.汉字.电话号码及混合搜索 二. 需求分析 英文名称及电话号码的搜索直接使用完全匹配的方式即可 重难点是汉字的拼音相关的拼音全拼.简拼搜索,比如 "刘亦菲" 对应的搜索关键字有且只有以下三大类总计 25 种匹配汉字:"刘"."亦".

  • vue2实现搜索结果中的搜索关键字高亮的代码

    具体代码如下所示: // 筛选变色 brightenKeyword(val, keyword) { val = val + ''; if (val.indexOf(keyword) !== -1 && keyword !== '') { return val.replace(keyword, '<font color="#409EFF">' + keyword + '</font>') } else { return val } } // 或者用

  • angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例

    本篇angular2/ionic2 实现搜索结果中的搜索关键字高亮的示例,分享给大家,具体如下: 添加一个pipe: import { Pipe, Injectable, PipeTransform } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; @Pipe({ name: 'keyword' }) @Injectable() export class KeywordPipe im

  • 在 Angular 中实现搜索关键字高亮示例

    在 Angular 中,我们不应该试图直接修改 DOM 的内容,当需要更新 DOM 内容的时候,应该修改的其实是我们的数据模型,也就是 $scope 中的数据,Angular 会帮助我们将修改之后的数据展示在页面中. 但是,在有些情况下,比如我们有一个搜索框,希望将搜索的关键字在正文中高亮出来,这时候就会感觉比较吃力了,filter 可以帮助我们处理这种情况. 实际上,很多时候,我们的数据是不能直接输出到 DOM 中的,典型的比如日期,或者货币等等,通常需要将我们内部的数据格式化之后,再输出到页

  • vue+Element实现搜索关键字高亮功能

    最近做了一个日志搜索的需求,要在页面上实现海量日志的关键字搜索.为了搜索更清晰,我最终实现了多条件搜索,且搜索结果的记录中的关键字全部高亮. 一.实现思路 1 实时监控表格,实现关键字的定位: 2 点击搜索按钮以后,实现记录中关键字的样式变化(即高亮). 二.实现过程 1 搜索条件表单 了解了实现思路,就让我们一起来看一下实现过程(关键位置均给了注释) <el-form :inline="true" :model="formQuery" > <el

  • Angularjs实现搜索关键字高亮显示效果

    需求分析: 根据关键字搜索网页内容,并且高亮显示内容中的关键字 细节分析: 1.每次执行搜索操作,需清空上一次结果 2.需区分html标签和正常文本内容,否则为关键字添加样式以后会出现标签内容被显示的情况 代码思路: 利用正则表达式匹配关键字 使用javascript字符串替换的方式,将关键字替换成<span class='red'>关键字</span> 为了避免出现当关键字为 'p' 时候,将标签<p>替换成<<span>p</span>

  • 如何实现IOS_SearchBar搜索栏及关键字高亮

    搜索框的效果演示: 这个就是所谓的搜索框了,那么接下来我们看看如何使用代码来实现这个功能. 我所使用的数据是英雄联盟的英雄名单,是一个JSON数据的txt文件, JSON数据的处理代码如下所示: //获取文件的路径path NSString *path = [[NSBundle mainBundle] pathForResource:@"heros" ofType:@"txt"]; //将路径下的文件转换成NSData数据 NSData *data = [NSDat

  • vue中的搜索关键字实例讲解

    目录 vue的搜索关键字 1.定义一个搜索框 2.循环遍历,之前 3.在data中,我们写入如下数据 4.在methods中 5.我们还可以这样写 搜索功能及搜索结果关键字高亮 首先实现搜索功能 通过computed计算属性监听搜索内容的变化 下边实现搜索关键字高亮显示 vue的搜索关键字 1.定义一个搜索框 <label>     搜索关键字:     <input type="search" name="" id="" va

  • JavaScript正则方法replace实现搜索关键字高亮显示

    前言 正则表达式是字符串处理工具中强有力的工具.也有人认为这只是一个小玩具,但不管怎么说都离不开它. 这里介绍的是JavaScript的正则表达式的replace方法 ,和实现搜索关键字高亮的功能. 先介绍一下正则表达式的replace方法 replace介绍 w3school原文链接介绍 正则表达式如何使用特殊字符$来表示原来的文本,这是实现搜索高亮的关键, var str = "asad sad 123 sd qwe21"; str.replace(/\d+/img,"数

  • jQuery zTree搜索-关键字查询 递归无限层功能实现代码

     唠叨一哈 前两天朋友跟我说要一个ztree的搜索功能,我劈头就是一巴掌:这种方法难道无数前辈还做少了?自己去找,我很忙~然后我默默地蹲着写zTree的搜索方法去了.为什么呢?因为我说了句"找不到是不可能的啊,肯定有很多人早做了无数了,找不到我给你写还请你恰午饭",然而我也去找了很久也没有找到(泪崩,我的计划,我的午饭~).绝大多数都是用的API里面的getNodesByParamFuzzy()或者高亮之类的.然而朋友表示需求不符合:1. 匹配失败父节点也隐藏:2.能自定义匹配规则,即

随机推荐