ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

typeahead.js 完整指南:基于 jQuery 的高性能自动补全库与 Bloodhound 建议引擎

typeahead.js 完整指南:基于 jQuery 的高性能自动补全库与 Bloodhound 建议引擎 typeahead.js 完整指南基于 jQuery 的高性能自动补全库与 Bloodhound 建议引擎【免费下载链接】typeahead.jstypeahead.js is a fast and fully-featured autocomplete library项目地址: https://gitcode.com/gh_mirrors/ty/typeahead.js导读typeahead.js 是一款受 Twitter 搜索自动补全功能启发而诞生的 JavaScript 自动补全autocomplete库。它由建议引擎 Bloodhound与UI 视图 Typeahead两个组件构成前者负责计算匹配建议后者负责渲染建议与处理 DOM 交互两者既可独立使用也可组合成完整的 typeahead 体验。本文将以仓库 README 为主线结合源码与官方文档完整讲解安装方式、两大组件的 API 与全部配置项、浏览器支持、版本策略、测试与开发工作流帮助你在实际项目中快速集成并深度定制自动补全能力。一、项目概览两个组件的架构设计README 明确指出typeahead.js 由两个核心组件构成Bloodhound建议引擎负责为给定查询计算建议。支持硬编码数据、初始化时预取prefetch、智能缓存、快速查找以及用远程数据回填backfill不足的结果。TypeaheadUI 视图以 jQuery 插件形式提供负责渲染建议、展示提示hint并处理全部 DOM 交互。两者可以单独使用但组合使用能提供最丰富的体验。从源码结构看这一分层非常清晰引擎侧src/bloodhound/目录下包含 bloodhound.js引擎主体、search_index.js内部搜索索引、prefetch.js、remote.js、transport.js网络传输、persistent_storage.js本地存储、lru_cache.jsLRU 缓存、tokenizers.js分词器与 options_parser.js选项解析。UI 侧src/typeahead/目录下包含 plugin.jsjQuery 插件入口、typeahead.js核心控制器、input.js输入框、menu.js菜单、dataset.js数据集、event_bus.js事件总线、highlight.js高亮等。在 Gruntfile.js 的构建文件清单中bloodhound与typeahead两组源文件被分别合并这印证了两组件的独立性bloodhound组产出独立的bloodhound.jstypeahead组产出独立的typeahead.jquery.js二者合并后即为typeahead.bundle.js。二、获取与安装README 提供了多种获取方式按偏好程度排列首选方式Bower 安装$ bower install typeahead.js其他方式下载最新版本的 zip 包单独下载最新的 dist 产物文件bloodhound.js—— 独立建议引擎typeahead.jquery.js—— 独立 UI 视图typeahead.bundle.js—— bloodhound.js 与 typeahead.jquery.js 的合并包最常用typeahead.bundle.min.js—— 上述合并包的压缩版。从 package.json 可以看出main字段指向dist/typeahead.bundle.js说明合并包是 npm 环境下的标准入口name与descriptionfast and fully-featured autocomplete library也与 README 的项目定位一致。重要依赖说明无论bloodhound.js还是typeahead.jquery.js都依赖jQuery 1.9README 声明package.json的dependencies中声明为jquery: 1.7实际使用请以 1.9 为准。集成时务必在引入 typeahead.js 之前引入满足版本要求的 jQuery。三、Bloodhound 建议引擎详解Bloodhound 是 typeahead.js 的大脑对应的完整官方文档见 doc/bloodhound.md。它的核心能力包括支持硬编码数据local初始化时预取数据prefetch降低建议延迟智能利用本地存储减少网络请求从远程源回填建议remote对远程请求做限流rate-limit与缓存减轻服务端负载。3.1 基础用法与完整 API创建一个引擎并传入一个 options 哈希即可var engine new Bloodhound({ local: [dog, pig, moose], queryTokenizer: Bloodhound.tokenizers.whitespace, datumTokenizer: Bloodhound.tokenizers.whitespace });Bloodhound 暴露了以下实例方法Bloodhound.noConflict()—— 返回Bloodhound引用并将window.Bloodhound还原为旧值用于避免命名冲突var Dachshund Bloodhound.noConflict();Bloodhound#initialize(reinitialize)—— 启动引擎初始化。初始化过程会把local与prefetch提供的数据加入内部搜索索引并建立remote使用的传输机制。在调用#initialize之前#get与#search实际上是空操作。除非将initialize选项设为false构造函数会隐式调用它var engine new Bloodhound({ initialize: false, local: [dog, pig, moose], queryTokenizer: Bloodhound.tokenizers.whitespace, datumTokenizer: Bloodhound.tokenizers.whitespace }); var promise engine.initialize(); promise .done(function() { console.log(ready to go!); }) .fail(function() { console.log(err, something went wrong :(); });初始化返回 jQuery Promise。后续再次调用#initialize时若reinitialize为假值则不重复执行初始化逻辑直接返回首次调用得到的同一个 Promise若为真值则如同首次调用一样重新初始化。Bloodhound#add(data)—— 将数组数据加入内部搜索索引engine.add([{ val: one }, { val: two }]);Bloodhound#get(ids)—— 返回搜索索引中对应ids的数据var engine new Bloodhound({ local: [{ id: 1, name: dog }, { id: 2, name: pig }], identify: function(obj) { return obj.id; }, queryTokenizer: Bloodhound.tokenizers.whitespace, datumTokenizer: Bloodhound.tokenizers.whitespace }); engine.get([1, 3]); // [{ id: 1, name: dog }, null]Bloodhound#search(query, sync, async)—— 返回匹配query的数据。本地搜索索引中的匹配结果传给sync回调若传给sync的数据不足sufficient条会请求remote数据并传给async回调engine.search(myQuery, sync, async); function sync(datums) { console.log(datums from local, prefetch, and #add); console.log(datums); } function async(datums) { console.log(datums from remote); console.log(datums); }Bloodhound#clear()—— 清空由local、prefetch与#add填充的内部搜索索引engine.clear();此外从 bloodhound.js 源码还可以看到两个缓存清理方法clearPrefetchCache()清空 prefetch 本地存储缓存与clearRemoteCache()调用Transport.resetCache()重置传输层缓存以及供 jQuery 插件内部集成的__ttAdapter()方法返回适配器函数将search(query, sync, async)包装为数据集source的签名ttAdapter()是它的废弃别名。3.2 Options 配置项实例化 Bloodhound 时可配置的选项如下datumTokenizer—— 签名为(datum)的函数将一条 datum 转换为字符串 token 数组。必填。queryTokenizer—— 签名为(query)的函数将查询转换为字符串 token 数组。必填。initialize—— 若为false构造器不会隐式初始化。默认true。identify—— 给定一条 datum返回其唯一 id 的函数。默认JSON.stringify。强烈建议覆盖此选项否则对象字段顺序或引用变化都会影响去重与索引。sufficient—— 当内部搜索索引提供的数据条数小于该值时#search会触发remote回填。默认5。sorter—— 用于对内部搜索索引返回数据进行排序的比较函数。local—— 数据数组或返回数据数组的函数。#initialize时加入内部搜索索引。prefetch—— 指向包含数据数组的 JSON 文件的 URL或一个 prefetch 选项哈希。remote—— 当内部数据不足时用于取数的 URL或一个 remote 选项哈希。3.3 Prefetch预取与本地存储缓存Prefetch 数据在初始化时被获取并处理。若浏览器支持本地存储处理后的数据会缓存在本地存储中从而在后续页面加载时避免额外的网络请求。警告尽管小数据集可以这么用prefetch 数据不应包含完整数据集而应作为第一级缓存first-level cache。无视此警告可能触及本地存储容量上限。配置 prefetch 可用以下选项url—— 预取数据加载的 URL。必填。cache—— 若为false不读写本地存储初始化时总是从url加载。默认true。ttl—— 预取数据在本地存储中的缓存时长毫秒。默认864000001 天。cacheKey—— 数据在本地存储中的键名。默认取url的值。thumbprint—— 用于指纹校验预取数据的字符串。若与本地存储中的不一致会重新获取数据。prepare—— 请求即将发出前允许你调整传给transport的 settings 对象的钩子。签名prepare(settings)应返回 settings 对象。默认为恒等函数。transform—— 签名transform(response)允许你在 Bloodhound 处理响应前转换预取响应。默认为恒等函数。从源码看_loadPrefetch的流程是若未配置 prefetch 直接 resolve否则先尝试prefetch.fromCache()读取本地缓存命中则用this.index.bootstrap(serialized)直接灌入索引未命中则prefetch.fromNetwork(done)从网络加载成功后this.add(data)并将this.index.serialize()序列化结果通过store写回缓存见 bloodhound.js。3.4 Remote限流、回填与去重Bloodhound 只有在内部搜索引擎无法提供足够结果时才访问网络。为防止对远端接口发出过量请求远程请求会做限流。配置 remote 可用以下选项url—— 远程数据加载的 URL。必填。prepare—— 请求即将发出前的钩子。签名prepare(query, settings)其中query是#search调用时的查询词settings是 Bloodhound 内部创建的默认 settings 对象函数应返回 settings 对象。默认为恒等函数。wildcard——prepare的便捷选项。若设置prepare会被替换为将url中的该占位符替换为 URI 编码后的查询词。rateLimitBy—— 限流方式debounce或throttle。默认debounce。rateLimitWait—— 限流的时间间隔毫秒。默认300。transform—— 签名transform(response)允许你在 Bloodhound 处理前转换远程响应。默认为恒等函数。从 bloodhound.js 源码可以确认search的完整流程先对本地索引结果排序并同步回调若配置了 remote 且本地结果少于sufficient则调用this.remote.get(query, processRemote)异步拉取否则取消上次未发出的限流请求注释 #149 说明这是为了防止过期的限流请求被发出。远程结果返回后会通过identify与本地结果做去重剔除与本地重复的条目后交给async回调。四、jQuery#typeahead UI 组件详解Typeahead 的 UI 组件以 jQuery 插件形式提供负责渲染建议与处理 DOM 交互完整官方文档见 doc/jquery_typeahead.md。其特性包括用户输入时实时展示建议将顶部建议显示为 hint背景提示文本支持自定义模板UI 灵活对 RTL 语言与输入法IME支持良好在建议中高亮查询匹配触发自定义事件便于扩展。4.1 初始化与完整 APIjQuery#typeahead(options, [*datasets])—— 为给定的input[typetext]启用 typeahead 功能。options是配置哈希其后的若干参数是各数据集的配置哈希$(.typeahead).typeahead({ minLength: 3, highlight: true }, { name: my-dataset, source: mySource });从 plugin.js 源码看initialize同时支持两种签名function(o, dataset, dataset, ...)与function(o, [dataset, dataset, ...])数组会被_.isArray识别。初始化时会为每个 input 元素创建 hint 输入框、menu 菜单、EventBus、Input、Menu 与 Typeahead 实例并将highlight顶层配置继承到所有数据集_.each(datasets, function(d) { d.highlight !!o.highlight; })。容器与输入框会被包装并加上tt-系列 class提示框为空时自动创建。jQuery#typeahead(val)—— 返回 typeahead 当前值即用户输入到 input 元素中的文本var myVal $(.typeahead).typeahead(val);jQuery#typeahead(val, val)—— 设置 typeahead 的值。官方建议用它替代jQuery#val$(.typeahead).typeahead(val, myVal);jQuery#typeahead(open)/(close)—— 打开 / 关闭建议菜单$(.typeahead).typeahead(open); $(.typeahead).typeahead(close);jQuery#typeahead(destroy)—— 移除 typeahead 功能将 input 元素还原为初始状态$(.typeahead).typeahead(destroy);从源码看destroy会调用revert($input)恢复被修改的属性autocomplete、spellcheck、dir 等并拆掉包装结构再调用typeahead.destroy()销毁内部实例见 plugin.js 与revert实现。jQuery.fn.typeahead.noConflict()—— 返回 typeahead 插件引用并还原jQuery.fn.typeaheadvar typeahead jQuery.fn.typeahead.noConflict(); jQuery.fn._typeahead typeahead;另外plugin.js的methods中还实现了enable/disable/isEnabled、activate/deactivate/isActive、open/close/isOpen、select、autocomplete、moveCursor(delta)等控制方法均通过$.fn.typeahead(method, ...)字符串调用方式分发。4.2 Options 配置项初始化 typeahead 时的顶层配置highlight—— 若为true渲染建议时当前查询在文本节点中的匹配会被包进strong元素class 为{{classNames.highlight}}。默认false。hint—— 若为false不显示 hint。默认true。minLength—— 开始渲染建议前所需的最小字符数。默认1。从 typeahead.js 源码看minLength会做数字类型校验非数字时回退为 1。classNames—— 覆盖默认 class 名详见Class Names一节。4.3 Datasets数据集的配置一个 typeahead 由一个或多个数据集组成。当用户修改输入值时每个数据集都会尝试为新值渲染建议。大多数场景一个数据集即可只有当你想按类别对建议分组时才需要多个数据集——例如 twitter.com 的搜索把结果分为最近搜索、趋势和账号这正是多数据集适用的场景。数据集的配置项source—— 建议的后备数据源。签名为(query, syncResults, asyncResults)的函数syncResults用于同步计算出的建议asyncResults用于异步计算出的建议如来自 AJAX 请求。source也可以是 Bloodhound 实例引擎内部通过__ttAdapter适配。必填。async—— 告知数据集是否期望异步建议。若未设置会根据source的函数签名推断若source期望 3 个参数则async为true。name—— 数据集名称。会拼到{{classNames.dataset}}-之后作为容器元素的 class即tt-dataset-name。只能包含下划线、短横线、字母a-z和数字。默认是随机数。limit—— 显示的建议最大条数。默认5。display—— 决定一条建议的字符串表示用于选中建议后回填输入框。可以是键字符串也可以是(suggestion) string的函数。默认将建议对象字符串化。templates—— 渲染时使用的模板哈希。预编译模板是一个接收 JavaScript 对象作为第一个参数并返回 HTML 字符串的函数notFound—— 当给定查询 0 条建议时渲染。可为 HTML 字符串或预编译模板上下文含query。pending—— 当 0 条同步建议但预期有异步建议时渲染。可为 HTML 字符串或预编译模板上下文含query。header—— 数据集存在建议时渲染在顶部。可为 HTML 字符串或预编译模板上下文含query和suggestions。footer—— 数据集存在建议时渲染在底部。可为 HTML 字符串或预编译模板上下文含query和suggestions。suggestion—— 渲染单条建议。若设置必须是预编译模板关联的建议对象作为上下文。默认是display值包在div中即div{{value}}/div。4.4 自定义事件typeahead 生命周期中会在 input 元素上触发以下自定义事件可通过bind/on监听事件名触发时机回调参数typeahead:activetypeahead 进入 active 状态—typeahead:idletypeahead 进入 idle 状态—typeahead:open结果容器打开—typeahead:close结果容器关闭—typeahead:change输入框失焦且值相比获得焦点时有变化原生 change 事件的规范化版本—typeahead:render某数据集渲染了建议jQuery 事件对象、渲染的建议、是否异步获取的标记、所在数据集名称typeahead:select选中了一条建议jQuery 事件对象、被选中的建议对象typeahead:autocomplete发生自动补全jQuery 事件对象、用于补全的建议对象typeahead:cursorchange结果容器光标移动jQuery 事件对象、光标移动到的建议对象typeahead:asyncrequest发出异步建议请求jQuery 事件对象、当前查询、请求所属数据集名称typeahead:asynccancel异步请求被取消jQuery 事件对象、当前查询、请求所属数据集名称typeahead:asyncreceive异步请求完成jQuery 事件对象、当前查询、请求所属数据集名称示例$(.typeahead).bind(typeahead:select, function(ev, suggestion) { console.log(Selection: suggestion); });注意每个事件携带的参数并不相同请按上表核对各事件的具体参数列表。从 typeahead.js 源码可以印证这些事件的触发链路例如数据集渲染后触发render事件异步请求的发起/取消/完成分别触发asyncrequest/asynccancel/asyncreceive。键盘交互方面_onEnterKeyed在存在活动建议时执行select并阻止默认行为_onTabKeyed在有活动建议时选中、否则对顶部建议执行autocomplete方向键驱动moveCursor(±1)Esc 执行close。4.5 Class Names 默认样式类组件使用的默认 class 名如下用途默认 class初始化为 typeahead 的 inputtt-inputhint 输入框tt-hint菜单元素tt-menu数据集元素tt-dataset建议元素tt-suggestion菜单为空时添加tt-empty菜单打开时添加tt-open光标移动到的建议tt-cursor高亮文本的包裹元素tt-highlight通过classNames选项可覆盖任意默认值$(.typeahead).typeahead({ classNames: { input: Typeahead-input, hint: Typeahead-hint, selectable: Typeahead-selectable } });五、内置分词器TokenizersBloodhound 对数据与查询的 token 化依赖分词器源码见 tokenizers.js全部通过Bloodhound.tokenizers暴露Bloodhound.tokenizers.whitespace—— 按空白字符切分字符串str.split(/\s/)Bloodhound.tokenizers.nonword—— 按非单词字符切分str.split(/\W/)Bloodhound.tokenizers.obj.whitespace/obj.nonword—— 用于对象数据的版本通过Bloodhound.tokenizers.obj.whitespace(field1, field2)指定参与 token 化的字段返回一个可对 datum 进行多字段分词并合并结果的函数。使用时注意两个 tokenizer 必须配对使用数据分词与查询分词方式应一致否则匹配会失效。六、浏览器支持README 声明的支持范围ChromeFirefox 3.5Safari 4Internet Explorer 8Opera 11注意typeahead.js 未在移动端浏览器上测试。从源码看代码中有针对 IE 的兼容处理如typeahead.js中_hacks对 IE 滚动条点击导致 blur 的补丁、plugin.js中对dir属性 IE7 的容错说明其对老版本 IE 做了专门适配。七、版本策略README 说明版本号遵循major.minor.patch格式并遵循以下语义化版本规则破坏向后兼容的变更 → 递增 major不破坏向后兼容的新增功能 → 递增 minorBug 修复与杂项变更 → 递增 patch。当前仓库版本为0.11.1见 package.json。CHANGELOG.md与doc/migration/0.10.0.md提供了历史变更与迁移说明升级前建议查阅。八、测试与开发工作流8.1 运行测试测试使用Jasmine编写、由Karma驱动。安装依赖后用 PhantomJS 运行完整测试套件$ npm testpackage.json中对应的脚本是./node_modules/karma/bin/karma start --single-run --browsers PhantomJS见 package.json。仓库在 karma.conf.js 中维护测试运行配置测试用例分布在test/bloodhound/与test/typeahead/目录下如 bloodhound_spec.js、plugin_spec.js 等可用于验证各模块行为。8.2 从源码构建开发前需要安装开发依赖与 grunt-cli$ npm install $ npm install -g grunt-cli常用 Grunt 任务见 Gruntfile.jsgrunt build—— 从源码构建 typeahead.js。构建流程依次执行合并src/common/utils.js与src/bloodhound/生成临时 bloodhound.js合并src/common/utils.js与src/typeahead/生成临时 typeahead.jquery.js再用 grunt-umd 包装为 UMD 模块最终产出dist/bloodhound.js、dist/typeahead.jquery.js、dist/typeahead.bundle.js及其.min.js压缩版并写入版本号见 Gruntfile.js。grunt lint—— 用 JSHint 检查源码与测试文件。grunt watch—— 源文件修改后自动重新构建。grunt server—— 在localhost:8888提供仓库根目录文件方便用 test/playground.html 调试测试。grunt dev—— 并行运行grunt watch与grunt server。九、贡献与支持若计划为 typeahead.js 贡献代码请先阅读 CONTRIBUTING.md。新贡献者可以从标记为 entry-level 的 issue 入手——这类问题通常改动较小有助于熟悉代码库。发现 Bug 可到仓库 Issues 页面提交。一般性问题可咨询社区技术问题建议在 Stack Overflow 提问并打上 typeahead.js 标签。十、许可证typeahead.js 版权归 Twitter, Inc. 所有Copyright 2013 Twitter, Inc.以MIT License授权见 LICENSE可自由使用与二次分发。总结通过本文你可以看到typeahead.js 的价值在于把自动补全这个看似简单的交互拆解为两个可独立复用的层次Bloodhound 负责数据层的预取、缓存、限流与回填TypeaheadjQuery 插件负责 UI 层的渲染、键盘交互、提示与事件。无论是用localprefetch做离线优先的第一级缓存还是用remotewildcardrateLimitBy做后端建议服务的安全接入都能在官方文档与本文的配置说明中找到可落地的方案。结合 doc/bloodhound.md、doc/jquery_typeahead.md 与src/、test/目录下的源码你可以进一步深入每一个配置项背后的实现细节。【免费下载链接】typeahead.jstypeahead.js is a fast and fully-featured autocomplete library项目地址: https://gitcode.com/gh_mirrors/ty/typeahead.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表