如何制作HTML Emoji表情面板选择器?
- 内容介绍
- 文章标签
- 相关推荐
本文共计715个文字,预计阅读时间需要3分钟。
直接上手即可使用,核心是使用 `input` 触发弹层、`emoji-picker-element`(Web Component)或手动渲染 Unicode 表情序列。推荐优先使用 Web Component 方案——它体积小、无构建依赖、支持搜索和分组,且已通过 Chrome/Firefox/Safari 兼容性验证。
为什么不用 contenteditable 或 textarea 直接插入?
因为光标位置控制复杂,尤其在 iOS Safari 下容易丢失焦点或插入错位。更稳的做法是:把 Emoji 当作普通字符串拼接进目标元素的 value 或 textContent,再手动聚焦回输入框末尾。
- 对
input[type="text"]:用input.value += emoji,然后input.setSelectionRange(input.value.length, input.value.length) - 对
textarea:同理,但需注意换行符和光标在多行中的偏移计算 - 避免用
document.execCommand—— 已废弃,Safari 15+ 不支持
emoji-picker-element 的正确加载与事件绑定
它不是 npm 包,而是通过 ES Module 动态导入的 Web Component。不能直接写 <emoji-picker> 就完事,必须先注册:
<script type="module"> import 'https://cdn.jsdelivr.net/npm/@joeattardi/emoji-picker-element@^3/dist/index.min.js'; // 然后才能使用 </script>
关键事件是 emoji-click,监听时注意目标元素必须已挂载:
立即学习“前端免费学习笔记(深入)”;
- 用
document.querySelector('emoji-picker').addEventListener('emoji-click', e => { ... }) -
e.detail.unicode是标准 Unicode 字符串(如"?"),不是短码(如:smile:) - 如果需要兼容旧系统,可加一层
if (e.detail.unicode.length > 2) {...}判断是否为组合型 Emoji(如带肤色修饰符的 ??)
自定义表情面板时,哪些 Unicode 范围最实用?
别全量加载 3000+ Emoji。按高频使用筛选,能显著减少 DOM 节点数和首次渲染时间:
- 基础笑脸:
\u{1F600}–\u{1F64F}(U+1F600–U+1F64F) - 手势与人物:
\u{1F44B}–\u{1F9FF}(跳过中间大量冷门符号,重点取 U+1F44B, U+1F642, U+1F923 等) - 常用符号:
\u{2700}–\u{27BF}(装饰性符号,如 ✨✅❌) - 避开 U+1F900–U+1F9FF 中大量未广泛支持的“补充符号”,部分安卓 WebView 会显示为空白方块
真要自己渲染列表,就用 for...of 遍历字符串,别用 String.fromCodePoint() 拼接——后者对组合 Emoji(如 ?❤️??)支持差,易断裂。
本文共计715个文字,预计阅读时间需要3分钟。
直接上手即可使用,核心是使用 `input` 触发弹层、`emoji-picker-element`(Web Component)或手动渲染 Unicode 表情序列。推荐优先使用 Web Component 方案——它体积小、无构建依赖、支持搜索和分组,且已通过 Chrome/Firefox/Safari 兼容性验证。
为什么不用 contenteditable 或 textarea 直接插入?
因为光标位置控制复杂,尤其在 iOS Safari 下容易丢失焦点或插入错位。更稳的做法是:把 Emoji 当作普通字符串拼接进目标元素的 value 或 textContent,再手动聚焦回输入框末尾。
- 对
input[type="text"]:用input.value += emoji,然后input.setSelectionRange(input.value.length, input.value.length) - 对
textarea:同理,但需注意换行符和光标在多行中的偏移计算 - 避免用
document.execCommand—— 已废弃,Safari 15+ 不支持
emoji-picker-element 的正确加载与事件绑定
它不是 npm 包,而是通过 ES Module 动态导入的 Web Component。不能直接写 <emoji-picker> 就完事,必须先注册:
<script type="module"> import 'https://cdn.jsdelivr.net/npm/@joeattardi/emoji-picker-element@^3/dist/index.min.js'; // 然后才能使用 </script>
关键事件是 emoji-click,监听时注意目标元素必须已挂载:
立即学习“前端免费学习笔记(深入)”;
- 用
document.querySelector('emoji-picker').addEventListener('emoji-click', e => { ... }) -
e.detail.unicode是标准 Unicode 字符串(如"?"),不是短码(如:smile:) - 如果需要兼容旧系统,可加一层
if (e.detail.unicode.length > 2) {...}判断是否为组合型 Emoji(如带肤色修饰符的 ??)
自定义表情面板时,哪些 Unicode 范围最实用?
别全量加载 3000+ Emoji。按高频使用筛选,能显著减少 DOM 节点数和首次渲染时间:
- 基础笑脸:
\u{1F600}–\u{1F64F}(U+1F600–U+1F64F) - 手势与人物:
\u{1F44B}–\u{1F9FF}(跳过中间大量冷门符号,重点取 U+1F44B, U+1F642, U+1F923 等) - 常用符号:
\u{2700}–\u{27BF}(装饰性符号,如 ✨✅❌) - 避开 U+1F900–U+1F9FF 中大量未广泛支持的“补充符号”,部分安卓 WebView 会显示为空白方块
真要自己渲染列表,就用 for...of 遍历字符串,别用 String.fromCodePoint() 拼接——后者对组合 Emoji(如 ?❤️??)支持差,易断裂。

