移动端H5接AI对话的坑:键盘顶起与滚动到底

PC 上跑得好好的 AI 对话框,搬到 H5 上当晚就被测试同学按了一串 bug:输入框被键盘顶飞了、发完消息看不到最新回复、安卓上输入法选词时疯狂触发提交。移动端聊天框这点交互,水比想象深。把我趟过的坑串一遍。

键盘弹起把布局顶乱

iOS Safari 上,软键盘弹起时 window.innerHeight 不变,但可视区域被键盘盖了一截,固定在底部的输入框直接被推到键盘后面看不见。我先用了老办法 position: fixed + 监听 resize,时灵时不灵。

后来换成 visualViewport API,这玩意儿专门描述「真正能看到的那块」:

ini 复制代码
const vv = window.visualViewport!;
function syncInputBar() {
  // 键盘弹起后,可视区底部相对布局视口的偏移
  const offset = window.innerHeight - vv.height - vv.offsetTop;
  inputBar.style.transform = `translateY(-${Math.max(0, offset)}px)`;
}
vv.addEventListener('resize', syncInputBar);
vv.addEventListener('scroll', syncInputBar);

visualViewport 在 iOS 13+ 和现代安卓 webview 都支持了,比起手动监听 focus/blur 加 setTimeout 那套玄学补丁靠谱太多。说实话早几年没这 API 的时候,这块代码丑得我自己都不想看。

发完消息没滚到底

聊天框的天条:新消息进来要自动滚到最新。但有两个坑------

一是流式输出时内容高度一直在涨,得在每个 chunk 后都滚一次;二是如果用户正往上翻历史,你强行拽他到底部会很烦人。所以要判断「用户是不是本来就贴着底」:

ini 复制代码
function isNearBottom(el: HTMLElement, threshold = 80) {
  return el.scrollHeight - el.scrollTop - el.clientHeight < threshold;
}

function onChunk() {
  const stick = isNearBottom(scrollEl);
  appendText();
  if (stick) {
    // 移动端 scrollTo behavior:smooth 在快速流式时会打架,用 instant
    scrollEl.scrollTop = scrollEl.scrollHeight;
  }
}

我一开始用 behavior: 'smooth',结果流式吐字太快,平滑滚动还没到底新内容又来了,画面一直在追着跑、晕得很。换成直接赋值 scrollTop 反而稳。体验上「smooth」在高频场景就是个陷阱。

输入法选词触发提交

安卓上最阴的一个。绑 keydown 监听回车发送,结果用户用拼音输入法选词、按空格/回车确认候选时,也被当成「发送」给提交了,发出一堆半截拼音。

根因是中文输入法的 composition 过程。得用 compositionstart / compositionend 把这段「正在拼字」的窗口圈出来:

ini 复制代码
let composing = false;
input.addEventListener('compositionstart', () => { composing = true; });
input.addEventListener('compositionend', () => { composing = false; });
input.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.shiftKey && !composing) {
    e.preventDefault();
    submit();
  }
});

!composing 这个守卫一加,乱发拼音的问题当场消失。这个坑不光聊天框,所有带中文输入 + 回车提交的场景都该防。

一个没修干净的

iOS 上输入框 focus 时整个页面偶尔会被系统往上顶一段(rubber-band),visualViewport 也救不全。我加了 document.body.scrollTop = 0 兜底,大部分机型 OK,但某些老款 iPhone 还是会闪一下。这个我至今没根治,属于「能接受的瑕疵」,谁有干净解法求评论区赐教。

模型对话那截我直接接了讯飞 这类 MaaS 的现成 API,不碰后端算力,省下的力气全花在这些移动端交互细节上------前端的活已经够磨人了。

你们 H5 聊天框还踩过啥独门坑?评论区集邮,攒多了我出个续集。

相关推荐
FPGA信号处理1 天前
【模式识别】第三节课:分类误差的来源与线性分类器
人工智能·分类·数据挖掘
hrrrrxeeeee1 天前
电商从业者AI技能提升:证书选择与商品、客服、运营场景落地
人工智能
小和尚同志1 天前
1.8k star 的开源 token 使用量监控神器— TokenTracker
人工智能·ai编程
极客 - L U1 天前
神经网络 - 激活函数、损失函数、优化器
人工智能·深度学习·神经网络
数字融合1 天前
透明化视频三维矿山井下照明重建技术
人工智能·python·数码相机
yi0111 天前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
xiangzhihong81 天前
创之星花店多端业务闭环拆解
人工智能
奈落241 天前
AI 编程从助手到 Agent:基于两份资料看哪些环节可以交出去,哪些必须自己攥住
大数据·人工智能
Joker可视化开发平台1 天前
AI短剧接棒真人剧:开机量跌七成,普通人进场窗口在收窄
大数据·人工智能
澳鹏Appen1 天前
澳鹏电子书 | 强化学习环境:为AI智能体打造高保真训练场
人工智能