最稳妥方案是textarea+absolute定位表情面板,父容器设relative和flex布局,并监听键盘高度变化做兼容处理。

直接用 textarea + 绝对定位表情面板,是最常见也最容易翻车的方案。真机上软键盘一弹,iOS 会把 textarea 顶上去,但如果你的表情面板用了 position: fixed,它就会脱离文档流、错位甚至消失;Android 则可能因 WebView 渲染差异,让面板被键盘盖住。
表情面板必须用 absolute,且父容器要设 relative + flex 自适应
fixed 是陷阱,absolute 才可控。关键在于父容器必须同时满足两个条件:
- 设
position: relative,给绝对定位提供参照 - 用
display: flex; flex-direction: column;把输入框和表情面板包在一起,让它们高度联动 - 输入区(含
textarea)设flex-shrink: 0,表情区设flex: 1或固定高度,避免被压缩
这样键盘弹起时,整个父容器高度收缩,表情面板自然跟着上移,不会漂移。
监听键盘高度变化要用 uni.onKeyboardHeightChange,但 H5 要降级
这个 API 在 App 和小程序里能拿到实时键盘高度,在 H5 里完全不触发。别硬扛,得做兼容:
由于微信的大热,为了更好的方便使用微信的用户查询一些信息,这篇文章是入门级的微信公众平台开发教程,需要的朋友可以参考下 这篇入门教程将引导你完成如下任务: 创建百度云平台应用启用微信公众平台开发模式获取订阅、文字、图片、语音、视频消息回复文本、图文及音乐消息程序开发
- App / 小程序:直接监听
uni.onKeyboardHeightChange,更新bottom值 - H5 端:监听
window.addEventListener('resize'),结合document.activeElement === textareaRef判断是否为键盘触发;或用uni.getSystemInfo预估键盘高度(iOS 一般 216px,Android 多为 300–400px) -
微信小程序真机测试务必加
safe-area-inset-bottom样式,否则面板可能卡在安全区外
点不到表情图标?本质是事件穿透 + 焦点抢占
自定义表情按钮被点击无响应,90% 是因为事件冒泡到了 textarea,或者系统键盘抢了焦点:
- 小程序:给表情图标外层
view加catchtouchstart,彻底阻止冒泡 - App 端(iOS/Android):先调用
uni.hideKeyboard(),再显示表情面板;千万别在input的@focus回调里立刻 show 面板,会有约 100ms 延迟,建议用setTimeout(() => showEmoji(), 100) - Vue 模板中写
@touchstart.stop也能生效,但 catchtouchstart 更稳妥
几百个 emoji 卡顿?雪碧图 + computed 分页是刚需
本地加载几百个 PNG 表情图,首次点击面板卡顿不是因为图大,而是 image 组件批量渲染时每个都触发独立解码请求。H5 尤其明显:
- 所有表情合并为一张雪碧图(sprite),用
background-image+background-position定位,比单图快 3 倍以上 - 表情数据存 JSON,但别直接
v-for渲染全部;改用computed分页(如每页 20 个),配合唯一:key - App 端慎用 base64 表情图——打包后体积暴涨且无法按需加载;H5 可用,但单图压缩到 ≤2KB
最易被忽略的一点:App 端软键盘收起后,表情面板不会自动隐藏,必须手动监听 uni.onKeyboardHeightChange 中高度归零的时机,再执行隐藏逻辑。










