at.js 是一个轻量级且功能强大的 JavaScript 库,专门用于实现文本输入中的自动补全功能,尤其擅长处理“@”符号触发的用户提及、话题标签等场景,它被广泛应用于社交平台、评论系统、文档协作工具等需要高效输入交互的产品中,支持动态数据加载、自定义 UI 模板、多触发字符扩展等特性,能够显著提升用户体验,本文将详细介绍 at.js 的安装配置、基本使用、高级功能及常见问题解决方法。

安装与引入
at.js 的安装方式灵活,可根据项目需求选择 npm、yarn 或 CDN 引入。
npm/yarn 安装(推荐用于项目集成)
通过包管理器安装后,在项目中引入:
npm install at.js --save # 或 yarn add at.js
然后在 JavaScript 文件中导入:
import At from 'at.js';
CDN 引入(适合快速测试或简单页面)
在 HTML 文件中通过 script 标签直接引入:
<script src="https://unpkg.com/at.js@2.0.0/dist/at.js"></script>
CDN 方式会暴露全局变量 At,无需额外模块导入。
基本使用
at.js 的核心是通过绑定输入框,监听特定字符(默认为“@”)触发自动补全逻辑,以下是基础使用步骤:
初始化
首先准备一个文本输入框(input 或 textarea),并为其设置 id 或 class:

<input type="text" id="mention-input" placeholder="输入 @ 提及用户">
然后通过 JavaScript 初始化 at.js:
const mentionInput = document.getElementById('mention-input');
new At(mentionInput, {
data: ['张三', '李四', '王五'], // 本地数据源
displayTpl: '<li>${name}</li>', // 显示模板
insertTpl: '${name}', // 插入模板
});
核心配置参数
at.js 提供丰富的配置选项,以下为常用参数说明(可通过表格更直观展示):
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
at |
String/Array | 触发自动补全的字符,可支持多个(如 ['@', '#']) |
|
data |
Array/Function | [] | 数据源,可为静态数组或返回 Promise 的异步函数(如 async (query) => {...}) |
displayTpl |
String | ‘
‘ | 下拉列表项的 HTML 模板,支持 ${data}、${name} 等占位符 |
insertTpl | String | ‘${data}’ | 插入到输入框中的内容模板,可结合占位符定制格式 |
maxLen | Number | 5 | 最大匹配结果数量 |
startWith | Boolean | false | 是否必须从输入位置开始匹配(如输入“@张”时,仅匹配“张”开头的项) |
hideOnBlur | Boolean | true | 输入框失焦时是否隐藏下拉列表 |
事件处理
at.js 支持通过事件扩展功能,
matched:匹配到数据时触发,参数为匹配结果数组,可用于动态加载数据;inserted时触发,参数为插入的文本,可用于记录用户行为;replaced:替换文本时触发(如删除已插入的提及)。
示例:监听插入事件并打印日志
new At(mentionInput, {
// ...其他配置
}).on('inserted', (text) => {
console.log('用户插入了:', text);
});
高级用法
自定义模板与样式
通过 displayTpl 可定制下拉列表的 UI,例如显示用户头像和昵称:
new At(mentionInput, {
data: [
{ name: '张三', avatar: 'zhangsan.jpg' },
{ name: '李四', avatar: 'lisi.jpg' }
],
displayTpl: `
<li class="mention-item">
<img src="${avatar}" alt="${name}">
<span>${name}</span>
</li>
`,
insertTpl: '@${name}',
});
同时结合 CSS 美化样式:
.mention-item {
display: flex;
align-items: center;
padding: 5px;
}
.mention-item img {
width: 24px;
height: 24px;
border-radius: 50%;
margin-right: 8px;
}
异步数据加载
当数据量较大或需实时搜索时,可通过 data 参数传入异步函数:

new At(mentionInput, {
data: async (query) => {
const response = await fetch(`/api/search?q=${query}`);
return response.json(); // 返回 [{ name: '用户1' }, { name: '用户2' }]
},
displayTpl: '<li>${name}</li>',
insertTpl: '@${name}',
});
多触发字符扩展
同时支持“@”用户和“#”话题标签:
new At(mentionInput, {
at: ['@', '#'],
data: (at, query) => {
if (at === '@') {
return ['张三', '李四']; // 用户数据
} else if (at === '#') {
return ['前端开发', 'JavaScript']; // 话题数据
}
},
displayTpl: '<li>${at === "@" ? "@" : "#"}${data}</li>',
insertTpl: '${at === "@" ? "@" : "#"}${data}',
});
常见问题解决
样式冲突
at.js 生成的下拉列表可能被页面 CSS 覆盖,可通过 customClass 参数添加自定义类名,并明确 CSS 优先级:
new At(mentionInput, {
customClass: 'custom-at-dropdown',
// ...其他配置
});
.custom-at-dropdown ul.atwho-view {
z-index: 9999;
background: #fff;
}
移动端适配
移动端下拉列表可能超出屏幕,可通过 CSS 设置最大高度和滚动:
.custom-at-dropdown ul.atwho-view {
max-height: 200px;
overflow-y: auto;
}
相关问答 FAQs
Q1:at.js 如何支持多个触发字符(比如同时支持@和#)?
A:通过配置 at 参数为数组,并在 data 函数中根据触发字符返回对应数据。
new At(input, {
at: ['@', '#'],
data: (at, query) => {
if (at === '@') return ['用户1', '用户2'];
if (at === '#') return ['话题1', '话题2'];
return [];
},
displayTpl: `<li>${at === '@' ? '@' : '#'}${data}</li>`,
insertTpl: `${at === '@' ? '@' : '#'}${data}`,
});
Q2:在 React 中使用 at.js 时,如何避免组件重新渲染导致的事件监听失效?
A:使用 useRef 保存 DOM 元素引用,并在 useEffect 中初始化 at.js,依赖项设为空数组确保只初始化一次,组件卸载时需调用 destroy() 方法清理事件监听:
import { useEffect, useRef } from 'react';
import At from 'at.js';
function MentionInput() {
const inputRef = useRef(null);
useEffect(() => {
if (inputRef.current) {
const at = new At(inputRef.current, {
data: ['张三', '李四'],
});
return () => at.destroy(); // 清理
}
}, []);
return <input ref={inputRef} type="text" />;
}
通过以上方法,可灵活应对不同场景下的自动补全需求,充分发挥 at.js 的轻量与高效特性。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/47947.html