移动端软键盘
系统差异
在 Android 和 IOS 中呼出软键盘会有不同的表现
-Android:呼出软键盘,webview页面高度被压缩(监听resieze事件会触发)
-IOS:呼出软键盘,webview整体上移,高度不变(监听resieze事件不触发)
问题一 滑动操作导致输入框被挡住
原因: 在正常情况下当 input 或 textarea 元素 focus 时输入框都应该固定在软键盘上方,但由于业务内有【滚动至底部】的需求,在滚动后输入框随着去到了手机底部
解决方案:在滚动至底部的函数中手动触发一下 scrollIntoView 方法,可以通过 document 的 activeElement 元素判断当前是否有 TEXTAREA 或者 INPUT 元素聚焦(tagName返回的标签名一定是全大写)
function scrollToBottom() {
nextTick(() => {
messageListRef.value?.scrollIntoView({
behavior: 'smooth',
block: 'end',
});
const tagName = document.activeElement?.tagName;
if ((tagName === 'TEXTAREA' || tagName === 'INPUT') && isIOS) {
setTimeout(() => {
document.activeElement?.scrollIntoView();
}, 50)
}
});
}
问题二 IOS聚焦时webview未被顶起
原因【未知】: ,在操作页面内其它元素后,点击输入框webview不会被顶起,但实际上已经成功聚焦,且输入文本后 IOS 还会自动触发 scrollIntoView 方法。
解决方案: 在输入框元素 focus 时手动触发一下 scrollIntoView 方法,此处定时器的延迟,关乎到软键盘呼出动画的时长,目前测试出最低 200ms 的延迟能成功触发(如果聚焦时正常顶起页面,scrollIntoView触发的滑动高度为0,所以并不会影响)
function handleFocus(event: FocusEvent) {
const activeElement = document.activeElement;
if (event.target === activeElement && isIOS) {
setTimeout(() => {
document.activeElement?.scrollIntoView();
}, 350)
}
}