移动端项目中 ios 键盘弹出,页面会滚动到input位置
2026/1/14大约 1 分钟
移动端项目中 ios 键盘弹出,页面会滚动到 input 位置
1. 阻止 ios 默认行为,键盘弹出,浮在页面上
<div v-show="showKeyboard">
<!-- 遮罩 -->
<div class="fixed inset-0 bg-black/50 z-98" @click="handleClose"></div>
<!-- 输入框 -->
<div
class="fixed left-0 right-0 z-99 bg-white transition-all duration-500"
:style="{ bottom: keyboardHeight + 'px' }"
>
<div class="flex gap-2 p-3">
<!-- 真实 input 2:负责输入 -->
<input
ref="realInputRef"
v-model="message"
type="text"
placeholder="说点什么..."
class="flex-1 bg-gray-100 rounded-full px-4 py-2"
style="font-size: 16px"
@blur="handleBlur"
/>
<button
@click="handleSend"
class="px-4 py-2 bg-blue-500 text-white rounded-full"
>
发送
</button>
</div>
</div>
</div>// 点击触发 input
const handleTriggerClick = async () => {
showKeyboard.value = true;
await nextTick();
// 加上 preventScroll: true 就行
realInputRef.value?.focus({ preventScroll: true });
};2. 计算 keyboard 高度,设置 input bottom 的值
// 计算 高度
const keyboardHeight = ref(0);
onMounted(() => {
// 记录初始高度
initialHeight = window.visualViewport?.height || 0;
// 优先使用 visualViewport
if (window.visualViewport) {
console.log("使用 visualViewport API");
window.visualViewport.addEventListener(
"resize",
handleVisualViewportResize
);
window.visualViewport.addEventListener(
"scroll",
handleVisualViewportResize
);
} else {
console.log("降级使用 window.resize");
window.addEventListener("resize", handleWindowResize);
}
});
onUnMounted(async () => {
if (window.visualViewport) {
window.visualViewport.removeEventListener(
"resize",
handleVisualViewportResize
);
window.visualViewport.removeEventListener(
"scroll",
handleVisualViewportResize
);
} else {
window.removeEventListener("resize", handleWindowResize);
}
});
// 方案1: visualViewport (iOS 13+, Chrome 61+)
function handleVisualViewportResize() {
if (!window.visualViewport) return;
const vpHeight = window.visualViewport.height;
// 键盘高度 = 窗口高度 - 可视区域高度
const kbHeight = initialHeight - vpHeight;
if (kbHeight > 100) {
// 键盘至少 100px
keyboardHeight.value = kbHeight;
} else {
keyboardHeight.value = 0;
}
console.log("visualViewport - 键盘高度:", kbHeight);
}
// 方案2: window.resize (降级方案)
let initialHeight = 0;
function handleWindowResize() {
if (initialHeight === 0) {
initialHeight = window.innerHeight;
return;
}
const currentHeight = window.innerHeight;
const diff = initialHeight - currentHeight;
if (diff > 100) {
keyboardHeight.value = diff;
} else {
keyboardHeight.value = 0;
}
console.log("window.resize - 键盘高度:", diff);
}