web视图改成页面视图_为何您的Web视图在滚动视图中消失

web视图改成页面视图

Placing a WebView inside a Scrollview can be problematic. The problem you would immediately come across is the WebView mysteriously disappearing. It IS in fact rendered but merely with a 0px height as it has not inherited the containing ScrollView height.

将WebView放在Scrollview中可能会出现问题。 您将立即遇到的问题是WebView神秘消失。 实际上,它已渲染,但高度仅为0px,因为它没有继承包含ScrollView的高度。

我为什么要这样做? (Why would I want to do this?)

I’m glad you asked. You might be wondering because WebViews naturally support scrolling with scrollEnabled=true . So, it does sound odd why you would wrap it in a ScrollView for this reason alone. You are correct, if that’s all you need then you should stop here. There is no need to complicate things.

我很高兴你问。 您可能想知道,因为WebView自然支持使用scrollEnabled=true滚动。 因此,仅出于这个原因,为什么将其包装在ScrollView中听起来确实很奇怪。 您是正确的,如果仅此而已,则应在此处停止。 无需使事情复杂化。

There are however many legitimate reasons. I think by far the most popular is when you want a hero banner or a nice native carousel above the WebView content and would like the native elements and WebView to scroll smoothly. If this sounds like you then read on!

但是,有许多合理的理由。 我认为到目前为止最受欢迎的是,您希望在WebView内容上方放置一个英雄横幅或一个漂亮的本地轮播,并希望本地元素和WebView平滑滚动。 如果听起来像您,请继续阅读!

怎么不做呢! (How not to do it!)

To resolve the issue you might have tried this:

要解决此问题,您可能尝试过此操作:

<ScrollView 
<WebView />
</ScrollView>

Yes, there is a contentContainerStyle which is applied to the actual View inside the ScrollView that encapsulates child components. This is one step closer to what we’re looking for since now you can actually see the WebView as it is inheriting the ScrollView height correctly.

是的,有一个contentContainerStyle应用于封装了子组件的ScrollView内部的实际View。 这距离我们正在寻找的目标又近了一步,因为现在您可以实际看到WebView,因为它正确地继承了ScrollView的高度。

However, this is NOT what I consider a working solution as the results are undesirable. If the webpage inside the WebView is taller than the WebView itself the rest of the webpage content is cutoff. Another undesirable result is the inner scroll. The WebView and ScrollView are now both scrollable and interfering with each other. Some developers may try to solve this by disabling WebView scrolling and setting a height to the WebView that is really high in value in order to accommodate the contained webpage content. Again, this is not what I call a solution. That’s just plain laziness!

但是,这不是我认为可行的解决方案,因为结果是不理想的。 如果WebView内的网页比WebView本身高,则其余网页内容将被截断。 另一个不良结果是内部涡旋。 现在,WebView和ScrollView都是可滚动的并且相互干扰。 一些开发人员可能试图通过禁用WebView滚动并为WebView设置一个高度很高的高度来解决此问题,以适应所包含的网页内容。 同样,这不是我所说的解决方案。 那简直就是懒惰!

那么聪明的解决方案是什么? (So what’s the solution smart arse?)

Well, you know how not to do it, and you already know the pitfalls and some half working solutions. Since we already know that the WebView inherits its height from its container and we know that if we set the WebView height tall enough and disable scrolling we will be able to view the entire page up to the set height.

好吧,您知道如何不这样做,并且您已经知道了陷阱和一些可行的解决方案。 因为我们已经知道WebView从其容器继承了它的高度,并且我们知道,如果我们将WebView的高度设置得足够高并禁用滚动,我们将能够查看整个页面直到设置的高度。

Setting the height is the key, however, it needs to be set dynamically based on the height of the dynamically loaded webpage content. To do this, we first need to determine the height of the webpage and then somehow relay this message back to the Native side so it could update the WebView height.

设置高度是关键,但是,需要根据动态加载的网页内容的高度来动态设置高度。 为此,我们首先需要确定网页的高度,然后以某种方式将此消息中继回本机端,以便可以更新WebView的高度。

We could put a snippet of JavaScript at the bottom of the webpage page with a postMessage trigger and tell it the page’s body height using DOM properties scrollHeight and offsetHeight:

我们可以使用postMessage触发器在网页页面的底部scrollHeight并使用DOM属性scrollHeightoffsetHeight告诉它页面的身高:

window.ReactNativeWebView.postMessage(
Math.max(document.body.offsetHeight, document.body.scrollHeight)
);

It’s not always viable to put a snippet in a webpage specific to RNWebView as the webpage might also be served in a browser or published by a third-party. Luckily you don’t have to. You could use WebView’s injectedJavascript to inject this snippet dynamically. Here’s how the solution looks like now:

在特定于RNWebView的网页中放置摘要并不总是可行的,因为该网页也可能在浏览器中提供或由第三方发布。 幸运的是,您不必这样做。 你可以使用的WebView injectedJavascript动态地注入这个片段。 解决方案如下所示:

<ScrollView contentContainerStyle={{
flexGrow: 1,
height: webViewHeight
}}>
<WebView
scrollEnabled={false}
onMessage={onMessage}
injectedJavaScript={injectedJavaScript}
/>
</ScrollView>

Where:

哪里:

const [webViewHeight, setWebViewHeight] = React.useState(null);
const onMessage = (event) => {
setWebViewHeight(Number(event.nativeEvent.data));
}
const injectedJavaScript=`
window.ReactNativeWebView.postMessage(
Math.max(document.body.offsetHeight, document.body.scrollHeight)
);
`

That’s it! As simple as that!

而已! 就如此容易!

谢谢! (Thank you!)

Thanks for reading to the end. Here’s a bonus for those who bothered to get this far! Here’s a fully working Expo Snack example that you can run on a real device and for you to clone, play and break!

感谢您阅读到底。 对于那些努力做到这一点的人来说,这是奖金! 这是一个可以正常运行的Expo Snack示例,您可以在真实设备上运行该示例,并对其进行克隆,播放和中断!

进一步说明 (Further Notes)

  • The injected JavaScript snippet is only valid for the first rendered webpage. If your WebView supports browsing then you will have to re-inject the snippet again on each page load.

    注入JavaScript代码段仅对第一个呈现的网页有效。 如果您的WebView支持浏览,那么您将不得不在每次加载页面时再次重新插入该代码段。

翻译自: https://medium.com/@caphun/reactnative-why-your-webview-disappears-inside-scrollview-c6057c9ac6dd

web视图改成页面视图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值