iOS Safari中键盘弹出时页面上移及失焦恢复的实现方案
解决iPhone Safari中输入框被键盘遮挡的问题
在iPhone Safari中,键盘弹出会挤压视口高度,导致页面下方的输入框被遮挡。以下是直接可行的实现方案,同时支持失焦后恢复页面原位置:
实现逻辑
核心是通过监听输入框的焦点/失焦事件,在焦点触发时计算输入框位置并调整页面滚动,失焦时回滚到原位置。由于Safari没有直接的键盘弹出事件,我们通过延迟执行来等待键盘完全展开后再计算。
代码实现
JavaScript 核心逻辑
// 存储页面初始滚动位置 let originalScrollPosition = 0; // 为所有输入框绑定事件 document.querySelectorAll('input, textarea').forEach(input => { // 输入框获取焦点时处理 input.addEventListener('focus', () => { // 记录当前滚动位置 originalScrollPosition = window.pageYOffset || document.documentElement.scrollTop; // 延迟执行,等待键盘完全弹出(时间可根据测试调整) setTimeout(() => { const inputRect = input.getBoundingClientRect(); // 计算输入框底部到视口底部的差值,加上20px的安全间距 const needScroll = inputRect.bottom + 20 - window.innerHeight; // 只有当输入框会被遮挡时才滚动 if (needScroll > 0) { window.scrollTo({ top: originalScrollPosition + needScroll, behavior: 'smooth' // 平滑滚动,可移除改为即时滚动 }); } }, 300); }); // 输入框失去焦点时恢复原位置 input.addEventListener('blur', () => { window.scrollTo({ top: originalScrollPosition, behavior: 'smooth' }); }); });
可选CSS优化
确保页面可正常滚动,避免因固定布局导致的异常:
body { min-height: 100vh; overflow-y: auto; }
注意事项
- 延迟时间调整:不同设备键盘弹出速度有差异,可在200-400ms之间调整
setTimeout的时间,确保键盘完全展开后再计算位置。 - 固定元素适配:如果页面有固定定位的头部/底部栏,计算时需要扣除这些元素的高度。例如存在固定底部栏时,将
window.innerHeight替换为window.innerHeight - footerOffsetHeight。 - 避免重复触发:如果页面有多个输入框,可优化事件绑定逻辑,避免重复监听。
内容的提问来源于stack exchange,提问作者Rue Vitale
相关产品推荐
相关产品推荐

