![](/img/trans.png)
[英]Is there any javascript event fired when the on-screen keyboard on mobile safari or chrome opens?
[英]How to fix viewport in place when virtual keyboard opens in mobile Safari?
在移动版 Safari 上,当虚拟键盘打开时,屏幕应呈现如下图像:
在哪里:
在移动版 Safari 上,当软键盘打开时,在输入或导航栏上拖动可以上下移动整个视口。
我有一个屏幕截图视频演示了这个问题: https : //youtu.be/GStBjRVpoGU
我已经在这个问题上花了几个月的时间,包括在 Stack Overflow 上浏览了许多类似的问题,但我一直无法找到一个有效的解决方案(或者,至少,一个我能够解决的问题)。
此应用程序是一个混合移动应用程序:使用 React.js 构建为 Web 应用程序,但使用 WebView 组件封装在 React Native 应用程序中。 然而,即使在普通的移动 Safari 窗口中打开 Web 应用程序,也存在同样的问题。
Mobile Safari 有一个相关问题,软键盘在打开时会将整个视口向上推,从而使视口的上半部分向上推离屏幕。 这个优秀的博客提供了该问题的描述和解决方案。 我实施了该解决方案。 它在软键盘打开时阻止了视口向上移动,但在软键盘打开后视口仍然可以滑动。
另一个问题是移动版 Safari 在打开/关闭软键盘时不会更新window.innerHeight
。 为了解决这个问题,我在 React Native 应用程序中使用了react-native-keyboard-spacer
,有点像这样:
render() {
return (
<React.Fragment>
<SafeAreaView >
<WebView/>
</SafeAreaView>
<KeyboardSpacer />
</React.Fragment>
);
}
这会在软键盘打开/关闭时更改 Webview 的高度,因此window.innerHeight
等也会更改。
position: fixed;
当软键盘打开时,移动版 Safari 效果不佳,所以我使用了position: absolute;
相反,感谢另一个非常有用的博客中的建议。
我创建了一个代码沙箱来演示这个问题。 在移动版Safari中打开,可以看到虚拟键盘打开后的屏幕滑动。 你也可以在这里查看实际的代码沙箱代码,它代表了我最接近解决这个问题的方法。
不过,关于代码沙箱需要注意的一件事。 没有 WebView 或 KeyboardSpacer:它只是一个网页。 因此,我不得不硬编码一些高度。但是如果你在移动版 Safari 中打开它,你会看到一旦软键盘打开,视口就会在整个地方滑动。
有没有人见过这个特定的问题? 你怎么修好它的? 提前谢谢了。
在JMathew的帮助下,我找到了解决此问题的方法。
请参阅此处的有效代码和框示例。
const messageListContainerRef = useRef<HTMLDivElement>(null);
//...
return (
//...
<div ref={messageListContainerRef}>
<MessageList/>
</div>
//...
)
inputContainerRef
和navbarContainerRef
。 使用它来防止触摸移动事件上的preventDefault()
,这将阻止用户能够上下滑动输入和导航栏。 例如:if (inputContainerRef.current) {
inputContainerRef.current.addEventListener('touchmove', (e) => {
e.preventDefault();
});
}
preventDefault()
。 相反,使用此解决方案通过设置scrollTop
值来防止用户滚动页面的底部(和顶部):if (messageListContainerRef.current) {
messageListContainerRef.current.addEventListener('touchmove', (e: any) => {
if (!e.currentTarget) {
return;
}
if (e.currentTarget.scrollTop === 0) {
e.currentTarget.scrollTop = 1;
} else if (e.currentTarget.scrollHeight === e.currentTarget.scrollTop +
e.currentTarget.offsetHeight) {
e.currentTarget.scrollTop -= 1;
}
});
}
根据您的需要/需要,您可以在组件安装上设置这些touchmove
事件侦听器,而不是在输入焦点上。 如果这对您有用,您甚至可以为整个 document.body 设置它们。
Javascript 解决方案,最后,我们得到了完美的解决方案。
window.scrollBy(0, 100); // Scroll 100px downwards
window.scrollBy(100, 0); // Scroll 100px to the right
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.