快速、功能齐全的独立自动完成库
?亮点?
在这里找到typeahead-standalone.js的详细文档和实时演示。
基本示例预览:
# you can install typeahead with npm
$ npm install --save typeahead-standalone
# Alternatively you can use Yarn
$ yarn add typeahead-standalone
然后将该库包含在您的应用程序/页面中。
作为一个模块,
// using ES6 modules
import typeahead from 'typeahead-standalone' ; // imports library (js)
import 'typeahead-standalone/dist/basic.css' ; // imports basic styles (css)
// using CommonJS modules
const typeahead = require ( 'typeahead-standalone' ) ;
require ( 'typeahead-standalone/dist/basic.css' ) ;
在浏览器上下文中,
<!-- Include the basic styles & the library -->
< link rel =" stylesheet " href =" ./node_modules/typeahead-standalone/dist/basic.css " />
< script src =" ./node_modules/typeahead-standalone/dist/typeahead-standalone.umd.js " > </ script >
<!-- Alternatively, you can use a CDN. For example, use jsdelivr to get the latest version -->
< link rel =" stylesheet " href =" https://cdn.jsdelivr.net/npm/typeahead-standalone/dist/basic.css " />
< script src =" https://cdn.jsdelivr.net/npm/typeahead-standalone " > </ script >
<!-- or use unpkg.com to get a specific version -->
< link rel =" stylesheet " href =" https://unpkg.com/[email protected]/dist/basic.css " />
< script src =" https://unpkg.com/[email protected]/dist/typeahead-standalone.umd.js " > </ script >
该库将在window.typeahead
中作为全局对象提供
Typeahead 需要一个input
元素来附加自身,以及一个Data source
(本地/远程)来显示建议。
这是一个非常基本的示例(有关高级示例,请参阅演示)
<!-- include the library -->
< script src =" ... " async > </ script >
<!-- Html markup -->
< input type =" search " id =" searchInput " autocomplete =" off " placeholder =" Search... " >
// local Data
const colors = [ 'Grey' , 'Brown' , 'Black' , 'Blue' ] ;
// input element to attach to
const inputElement = document . getElementById ( "searchInput" ) ;
typeahead ( {
input : inputElement ,
source : {
local : colors ,
// prefetch: {...}
// remote: {...}
}
} ) ;
您可以将以下配置选项传递给typeahead-standalone
:
范围 | 描述 | 默认 |
---|---|---|
input | DOM 输入元素必须与此参数一起传递,并且 typeahead 会将其自身附加到此字段。 | - (必需的) |
source | 这是计算建议的数据源。源可以是本地的、预取的或从远程端点检索的。细节 | - (必需的) |
minLength | 指定屏幕上应显示建议的最小长度。 | 1 |
limit | 指定应显示的最大建议数。 | 5 |
highlight | 查询中匹配的字母会在建议列表中突出显示。添加了一个tt-highlight 类,方便造型 | true |
autoSelect | 如果设置为 true,则预先选择第一个显示的建议 | false |
hint | 将输入占位符更新为等于第一个匹配的建议。添加了tt-hint 类以方便样式设置 | true |
diacritics | 启用/禁用语言变音符号支持搜索的标志(即通过将重音字符转换为其非重音对应字符进行搜索) | undefined |
classNames: Object | classNames 对象可用于为 DOM 中注入的每个 html 元素设置自定义类。细节 | undefined |
templates | 包含页眉、页脚、建议、组和未找到状态模板的对象。请参阅模板部分以获取说明 | undefined |
preventSubmit | 如果您的输入元素在表单元素内使用,则此标志允许阻止按下 ENTER 键时的默认提交操作。 | false |
onSubmit(event, selectedItem?) | 当您想在表单元素外部使用 typeahead 时,可以使用此处理程序来处理/提交输入值。按 ENTER 键时触发。第一个参数是键盘事件,第二个参数是所选项目,如果未选择任何项目,则为未定义 | undefined |
display(selectedItem, event?) => string | 当用户从建议中选择一个项目时,将执行此回调。当前建议/项目作为参数传递,它必须返回一个设置为输入值的字符串。第二个可选参数event 是鼠标/键盘事件,可用于跟踪用户交互或进行分析。它默认为null 。 | 返回所选项目的字符串表示形式 |
tokenizer?: (words: string) => string[] | 分词器函数用于按给定字符分割搜索查询和搜索数据。当您希望搜索连字符或具有特定前缀/后缀的单词时,此功能非常有用 | 单词由空格字符分割(换行符、制表符、空格) |
listScrollOptions?: ScrollIntoViewOptions | 允许对需要滚动的大量建议的滚动行为进行精细控制。这些选项被传递给scrollIntoView() 函数。 MDN 参考 | { block: "nearest", inline: "nearest", behaviour: "auto"} |
retainFocus | 此参数可用于控制建议列表打开时按“Tab”键的焦点。如果启用,它将选择突出显示的选项,然后将焦点返回到搜索输入。如果禁用,按“Tab”将选择突出显示的选项并将焦点移至表单中的下一个可聚焦项目 | true |
hooks | hooks 配置选项对于在 typeahead 生命周期中的特定时刻执行任意代码非常有用。细节 | 不明确的 |
这是提供建议的数据来源。这是源对象的预期格式。
source: {
local: [],
remote: {
url: 'https://remoteapi.com/%QUERY', // OR "url: (inputQuery: string) => `https://remoteapi.com/${inputQuery}`"
wildcard: '%QUERY',
debounce: 300 // optional, default => 200ms
requestOptions: {} // optional, default => undefined
},
prefetch: {
url: 'https://remoteapi.com/load-suggestions', // OR `url: () => string`
when: 'onFocus', // optional, default => 'onInit'
done: false, // optional, default => false
process: (items) => void, // optional, default => undefined
requestOptions: {} // optional, default => undefined
},
keys: ['...'], // optional (required when source => Object[])
groupKey: '...', // optional, default => undefined
identity: (item) => string, // optional (determines uniqueness of each suggestion)
transform: function (data) {
// modify source data if needed & return it
return data;
}
}
local
数据源。prefetch
数据源。您必须提供指向将返回建议的端点的url
参数。您可以提供一个可选的when
参数,该参数定义何时应发生预取请求。它默认为onInit
这意味着一旦 typeahead 初始化,建议就会被预加载。您可以将其设置为onFocus
这将导致仅当用户聚焦搜索输入框时才预加载建议。 done
标志是可选的,可用于以编程方式禁用预取请求。它的默认值为false
。当第一次预取数据时,它会自动设置为true
(以防止多个网络请求)。通过设置done: true
,预取请求将不会发生。执行此操作的一个示例用例是,当您使用localStorage存储建议,但 l ocalStorage之前已经存储了建议,从而无需再次预取数据。 process(suggestions)
回调是可选的。它在预取请求发生后执行。它接收转换后的建议作为参数,并且作为示例,可以将接收到的建议存储在localStorage中以供稍后使用。remote
数据源。remote
数据源时,必须设置url
和wildcard
选项。执行请求时, wildcard
将替换为搜索字符串。debounce
选项用于延迟 http 请求的执行(以毫秒为单位)。它是可选的,默认为 200ms。GET
。transform()
函数,该函数在预取/远程端点返回响应后立即被调用。您可以在 typeahead 处理响应之前对其进行修改。keys
数组。第一个键用于标识应将对象的哪个属性用作显示建议的文本。例如,假设数据源是这样的: /* Example Data source */
[
{ id : 1 , color : "Yellow" , meta : { colorCode : "YW" } } ,
{ id : 2 , color : "Green" , meta : { colorCode : "GN" } , shade : "Greenish" } ,
{ id : 3 , color : "Olive" , meta : { colorCode : "OV" } , shade : "Greenish" } ,
...
]
现在,如果我们希望使用color
属性中定义的文本作为建议显示,则键必须包含颜色作为第一个键。 (即keys: ["color"]
)。
如果您希望向搜索索引添加更多属性,您也可以在keys
数组中指定这些属性。通过一个例子可以最好地理解这一点。让我们采用与上面所示相同的示例数据源。如果您想通过另一个属性( colorCode )而不只是通过其颜色搜索颜色怎么办?为此,只需设置keys: ["color", "meta.colorCode"]
。如果您现在搜索“ YW ”,则会按预期弹出建议“黄色”。
groupKey: "shade"
时,建议将按属性“ shade ”进行分组。在此示例中,绿色和橄榄色将出现在“绿色”( shade
)组下,而黄色将没有组。 groupKey还支持使用点表示法访问嵌套属性。 (示例 - groupKey: "category.title"
)identity()
函数用于确定每个建议的唯一性。它接收建议作为参数,并且必须返回给定建议唯一的字符串。这是一个可选属性,默认返回与第一个键(即keys[0]
关联的值。但是,默认值可能并非每次都有效。例如,考虑以下代码 - /* Example Data source of Songs */
[
{ title : "God is Good" , artist : "Don Moen" } ,
{ title : "God is Good" , artist : "Paul Wilbur" } ,
{ title : "God is Good" , artist : "Micheal Smith" } ,
{ title : "El Shaddai" , artist : "Amy Grant" } ,
...
]
假设键设置为keys: ["title"]
。默认情况下, identity()
函数使用第一个键(即title )来确定唯一性。因此,如果您搜索God
,您会发现仅显示 1 个建议,因为有 3 首歌曲具有完全相同的title
属性。为了显示不同艺术家的所有 3 个建议,您需要设置identity
属性,使其返回一个唯一的字符串 -
identity ( item ) = > ` ${ item . title } ${ item . artist } ` ;
当您的数据源是对象数组时,强烈建议设置identity()
配置选项以返回唯一的字符串。
查看实时示例以获取进一步说明。
目前只有 1 个可用的钩子:
updateHits: async (resultSet, loader) => Promise<resultSet>
在搜索结果显示给用户之前执行,可用于覆盖搜索索引返回的建议。 (对于自定义排序、过滤、添加或删除结果很有用。这个钩子是一个异步函数,允许您在需要时发出 AJAX 请求来获取新结果) // Example usage of "updateHits" hook
typeahead ( {
input : document . querySelector ( ".myInput" ) ,
source : {
local : [ ] ,
// ...
} ,
hooks : {
updateHits : async ( resultSet , loader ) => {
resultSet . hits . push ( { name : "new suggestion" } ) ; // add new suggestion
// resultSet.hits.filter( ... ); // filter the suggestions
// resultSet.hits.sort( ... ); // custom sort the suggestions
// resultSet.count = 5000; // to set the total results found
/*** You can also make an AJAX request to fetch results ***/
// loader(); // display the loader template
// const response = await fetch('https://example.com');
// const text = await response.text();
// resultSet.hits = text && JSON.parse(text);
// loader(false); // hide the loader template
// resultSet.updateSearchIndex = true; // updates search index if necessary. Default `false`
return resultSet ; // you must return the resultSet
} ,
} ,
templates : {
loader : ( ) => { ... } ,
}
} ) ;
typeahead 提供了一些基本样式。用户界面完全由您决定,并且可以根据像素进行定制。您可以使用以下类来添加/覆盖样式。
typeahead-standalone
类的容器中。tt-input
类。tt-hint
类。tt-list
类的容器中。 (当没有建议可用时,添加一个类tt-hide
)tt-suggestion
类,如果该建议被选择,那么它还会另外有一个tt-selected
类。tt-highlight
类。您可以通过定位父选择器.typeahead-standalone
来添加自己的样式。例如,我们可以更新每个建议的背景颜色,如下所示 -
/* set background color for each suggestion */
. typeahead-standalone . tt-list . tt-suggestion {
background-color : green;
}
要覆盖默认样式,请设置配置选项className
并将其用作选择器。假设您设置了className: "my-typeahead"
,然后要覆盖悬停/选择建议时的样式,您可以使用:
/* override styles */
. typeahead-standalone . my-typeahead . tt-list . tt-suggestion : hover ,
. typeahead-standalone . my-typeahead . tt-list . tt-suggestion . tt-selected {
color : black;
background-color : white;
}
从v4.0
开始,JS 和 CSS 已经分离,可以更好地控制样式。整个 CSS 可以从 CDN 或下面检索,并直接复制到您的项目中,允许您根据需要丢弃/覆盖任何样式。
/***** basic styles *****/
. typeahead-standalone {
position : relative;
text-align : left;
color : # 000 ;
}
. typeahead-standalone . tt-input {
z-index : 1 ;
background : transparent;
position : relative;
}
. typeahead-standalone . tt-hint {
position : absolute;
left : 0 ;
cursor : default;
user-select : none;
background : # fff ;
color : silver;
z-index : 0 ;
}
. typeahead-standalone . tt-list {
background : # fff ;
z-index : 1000 ;
box-sizing : border-box;
overflow : auto;
border : 1 px solid rgba ( 50 , 50 , 50 , 0.6 );
border-radius : 4 px ;
box-shadow : 0 px 10 px 30 px 0 px rgba ( 0 , 0 , 0 , 0.1 );
position : absolute;
max-height : 70 vh ;
}
. typeahead-standalone . tt-list . tt-hide {
display : none;
}
. typeahead-standalone . tt-list div [ class ^= "tt-" ] {
padding : 0 4 px ;
}
. typeahead-standalone . tt-list . tt-suggestion : hover ,
. typeahead-standalone . tt-list . tt-suggestion . tt-selected {
background : # 55acee ;
cursor : pointer;
}
. typeahead-standalone . tt-list . tt-suggestion . tt-highlight {
font-weight : 900 ;
}
. typeahead-standalone . tt-list . tt-group {
background : # eee ;
}
您还可以使用模板添加页眉、页脚并进一步设置每个建议的样式。
模板可用于自定义列表的呈现。它们的使用完全是可选的。目前,有 7 个模板可用 -
templates: {
header : ( resultSet ) => '<h1>List of Countries</h1>' , /* Rendered at the top of the dataset */
footer : ( resultSet ) => '<div>See more</div>' , /* Rendered at the bottom of the dataset */
suggestion : ( item , resultSet ) => { /* Used to render a single suggestion */
return `<div class="custom-suggestion"> ${ item . label } </div>` ;
} ,
group : ( groupName , resultSet ) => { /* Used to render a group */
return `<div class="custom-group"> ${ groupName } </div>` ;
} ,
empty : ( resultSet ) => { /* Rendered when the input query is empty */
return `<div>Search for Colors...</div>` ;
// OR (to display some suggestions by default)
return [ { title : "France" } , { title : "Spain" } ] ;
}
loader : ( ) = > 'Loading...' , /* Rendered while awaiting data from a remote source */
notFound : ( resultSet ) => '<span>Nothing Found</span>' , /* Rendered if no suggestions are available */
}
如上所示,每个模板都需要一个回调,该回调必须返回一个string
,该字符串稍后被解释为 HTML。模板还接收一个参数resultSet
,其结构如下所示。
resultSet = {
query : '...' , // the input query
hits : [ ... ] , // found suggestions
count : 0 , // the total suggestions found in the search index
limit : 5 , // the number of suggestions to show
wrapper : DOMElement , // the container DOM element
}
为了方便样式设置,每个模板都包装在具有相应类的div
元素中。 IE
header
=> 类tt-header
footer
=> tt-footer
类suggestion
=> 类tt-suggestion
group
=> 类tt-group
loader
=> 类tt-loader
empty
=> 类tt-empty
notFound
=> 类tt-notFound
classNames
配置选项仅允许您根据您的选择替换默认的类名称。
typeahead 中使用的默认类名如下:
const classNames = {
wrapper : 'typeahead-standalone' , /* main container element */
input : 'tt-input' ,
hint : 'tt-hint' ,
highlight : 'tt-highlight' ,
list : 'tt-list' , /* container element for suggestions */
hide : 'tt-hide' ,
show : 'tt-show' ,
selected : 'tt-selected' ,
/* classes used within templates */
header : 'tt-header' ,
footer : 'tt-footer' ,
loader : 'tt-loader' ,
suggestion : 'tt-suggestion' ,
group : 'tt-group' ,
empty : 'tt-empty' ,
notFound : 'tt-notFound' ,
} ;
例如,如果您想为输入元素使用不同的类名,您可以像这样初始化 typeahead -
typeahead ( {
input : '...' ,
source : '...' ,
classNames : {
input : 'my-custom-input-class' // this class is used instead of tt-input
}
} ) ;
typeahead.reset()
typeahead.addToIndex()
typeahead.destroy()
reset(clearLocalSrc?: boolean)
将预输入实例重置为任何用户交互之前的状态。它会从搜索索引中删除所有项目(通过本地源添加的项目除外)。要绝对删除所有项目,该函数接受一个可选参数,该参数应设置为true
。 Reset() 还会清除缓存的远程请求。
const instance = typeahead ( { /* options */ } ) ;
// clear search index except items added via Local source
instance . reset ( ) ;
// clears entire search index
instance . reset ( true ) ;
当您需要在经过一定时间后使数据失效时,此 API 非常有用。
addToIndex()
将项目添加到搜索索引。当您想要自己获取数据然后将其添加到搜索索引时很有用。它类似于通过本地源添加项目。
const instance = typeahead ( { /* options */ } ) ;
instance . reset ( true ) ; // or instance.reset();
instance . addToIndex ( [ 'Blue, Baige , Black' ] ) ;
destroy()
销毁 typeahead 实例,清除搜索索引,删除所有事件处理程序并清理 DOM。如果您想禁用预输入,可以使用它。
const instance = typeahead ( { /* options */ } ) ;
instance . destroy ( ) ;
以下是可能遇到的错误代码的一个小词汇表
代码 | 描述 |
---|---|
e01 | 缺少输入 DOM 元素 |
e02 | 建议来源缺失/不正确。您必须至少提供 3 种可能的源之一 - 本地、预取或远程,并具有预期的源格式(参考) |
e03 | 钥匙丢失 |
e04 | 预取请求失败 |
e05 | 远程请求失败 |
有兴趣贡献功能和修复吗?
阅读更多关于贡献的内容。
查看变更日志
麻省理工学院 © DigitalFortress