在移动Safari上,打开虚拟键盘后,屏幕应呈现如下图所示:
其中:
在移动Safari上,当软键盘打开时,在输入或导航栏上拖动可以上下移动整个视口。
我有一个演示问题的屏幕录像:https://youtu.be/GStBjRVpoGU
我已经花了几个月的时间解决这个问题,包括在Stack Overflow上浏览许多类似的问题,但是我一直找不到能解决问题的解决方案(或者至少是我已经能够解决的解决方案)。
[此应用程序是一个混合移动应用程序:使用React.js作为Web应用程序构建,但使用WebView组件包装在React Native应用程序中。但是,即使在常规的移动Safari窗口中打开了Web应用程序,也存在相同的问题。
Mobile Safari存在一个相关问题,即软键盘在打开时会将整个视口向上推,从而将视口的上半部分向上推并移出屏幕。 This excellent blog同时提供了该问题的说明和解决方案。我实现了该解决方案。当软键盘打开时,它阻止了视口向上移动,但是在软键盘打开后,视口仍然可以在周围滑动。
[另一个问题是,打开/关闭软键盘时,移动Safari不会更新window.innerHeight
。为了解决这个问题,我在React Native应用程序中使用了react-native-keyboard-spacer
,有点像这样:
render() {
return (
<React.Fragment>
<SafeAreaView >
<WebView/>
</SafeAreaView>
<KeyboardSpacer />
</React.Fragment>
);
}
[这会在每次软键盘打开/关闭时更改Webview的高度,因此window.innerHeight
等也会更改。
[也众所周知,当打开软键盘时,移动Safari上的position: fixed;
不能很好地工作,因此,由于其他position: absolute;
的建议,我改用了very useful blog。
我创建了一个code sandbox来演示该问题。在打开虚拟键盘后,在移动Safari中将其打开以查看屏幕幻灯片。您也可以使用实际的代码沙箱代码here,它代表我最近解决此问题的方式。
不过,关于代码沙箱需要注意的一件事。没有WebView或KeyboardSpacer:它只是一个网页。因此,我必须对一些高度进行硬编码。但是,如果您在移动Safari中打开它,则一旦打开软键盘,视口就会在整个位置滑动。
以前有人见过这个特殊问题吗?你怎么修好它的?提前非常感谢。
请参见工作代码和框示例here。
const messageListContainerRef = useRef<HTMLDivElement>(null);
//...
return (
//...
<div ref={messageListContainerRef}>
<MessageList/>
</div>
//...
)
[打开虚拟键盘时(当虚拟输入被聚焦时),将用于touchmove事件的事件监听器添加到
inputContainerRef
和navbarContainerRef
。将其用于触摸移动事件上的preventDefault()
,这将防止用户能够上下滑动输入和导航栏。例如:
if (inputContainerRef.current) {
inputContainerRef.current.addEventListener('touchmove', (e) => {
e.preventDefault();
});
}
您仍然希望能够滚动查看消息列表,因此不能仅在其上单击
preventDefault()
。而是使用this solution通过设置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设置它们,如果那对您有用。