最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
HTML如何做@提及功能_html @提及at mention功能实现【代码解析】
时间:2026-07-29 16:53:55 编辑:袖梨 来源:一聚教程网
应监听 keydown + compositionend 组合事件捕获 @ 触发时机,插入 contenteditable="false" 的提及节点并手动设置光标位置,下拉列表需基于光标坐标动态定位且挂载至 body。
怎样使用 contenteditable 捕捉 @ 符号的触发时刻
仅仅监听 input 事件并不可靠,因为用户可能粘贴文字、通过方向键移动光标,或删除中间字符,从而使 @ 出现在不符合预期的位置。真正需要监听的是 keydown + compositionend 这一组合,重点识别按下 @ 键时光标位于行首,或其前一个位置为空白的瞬间。
操作建议:
立即学习前端免费学习笔记(深入);
- 在
keydown内部判断e.key === '@',随后通过getSelection().getRangeAt(0).startOffset取得光标位置,并向前检查一个字符是空格、换行还是开头 - 还必须同时监听
compositionend,否则在中文输入法环境下按完@不会触发,因为输入法会先发送合成事件) - 不要在
input中执行匹配,因为它不能分辨用户输入 @ 与粘贴含 @ 字符串两种行为,容易错误开启下拉列表
如何把 @xxx 显示为可点击标签,同时不破坏编辑流程
不能用纯文本拼接,也不能直接插入 <span> 后还指望光标正常进出——contenteditable 对嵌套内联元素的光标行为很敏感。正确做法是用 document.execCommand('insertHTML', false, ...) 或现代 getSelection().setBaseAndExtent() 配合 Range.insertNode() 插入带 data-mention-id 和 contenteditable="false" 的 <span>。
操作建议:
立即学习前端免费学习笔记(深入);
- 必须为插入的提及节点设置
contenteditable="false",否则双击后会进入编辑状态并破坏语义 - 添加
tabindex="0"以及role="button",使键盘用户能够聚焦,并通过回车触发详情 - 样式应采用
display: inline-flex+align-items: center,防止标签换行时被拆分 - 不要采用
white-space: nowrap,否则长昵称无法折行,还会溢出容器
@ 提及列表如何对齐光标,同时避免遮住输入内容
下拉列表不能依靠固定 top/left定位,而应在每次展示时计算光标相对于编辑区域的绝对坐标,再借助 getBoundingClientRect() 取得光标所在 Text 节点的末端位置,最后叠加滚动偏移。若直接写死 position: absolute; top: 200px ,遇到缩放、滚动或多行编辑时必然发生错位。
操作建议:
立即学习前端免费学习笔记(深入);
- 使用
window.getSelection().getRangeAt(0).getClientRects()获取最后一个DOMRect,其bottom可以作为下拉列表显示的基准线 - 列表容器需要挂载到
body下面(使用createPortal或者document.body.appendChild),以免被父容器overflow: hidden截断 - 监听
scroll以及resize事件以重新定位,同时加入throttle防抖,避免拖动滚动条时出现卡顿 - 列表项使用
aria-activedescendant实现键盘导航,不应只支持鼠标操作
为什么完成 @ 提及后继续输入,会出现吞字符或光标跳动
问题根源在于插入的提及节点属于 contenteditable="false",而紧邻它的文本节点依旧可编辑。浏览器对假内联块与真文本之间的光标合并机制并不统一:Chrome中光标可能卡在提及右侧,Safari则可能直接跳到下一行开头。
操作建议:
立即学习前端免费学习笔记(深入);
- 完成提及插入后,手动通过
Range把光标放至提及节点后面:先创建新的Range,range.setStartAfter(mentionNode),然后再selection.removeAllRanges()+selection.addRange(range) - 不允许用户在提及节点前后连续输入空格,应监听
input,判断光标附近是否出现两个空格,并自动trim()后重新设置光标 - 使用 React/Vue 时,提及节点外部不要再套响应式 wrapper,例如
<div><Mention /></div>),否则会增加额外的 DOM 层级,使光标异常更加严重
输入法兼容才是最难处理的部分:中文用户输入完“@张”但尚未选人便按下空格时,需要判断这是输入法中止信号,而不是真实空格,因此必须结合 compositionstart/compositionend 以及 keydown 的 key 状态进行交叉判断。对于这个边界情况,90% 的开源 mention 库都处理得不够准确。
相关文章
- 必由学怎么入门 07-30
- 浮生忆玲珑内存大小 浮生忆玲珑游戏介绍 07-30
- 浮生忆玲珑画匠牛攻略 浮生忆玲珑画匠牛是哪位 07-30
- 浮生忆玲珑好玩么 浮生忆玲珑游戏玩法特色介绍 07-30
- 浮生忆玲珑如何获得戏服 浮生忆玲珑戏服攻略 07-30
- 浮生忆玲珑桂花酱鸡做法 浮生忆玲珑桂花酱鸡攻略 07-30