React native:是否可以在 webview 中设置 html 内容的高度?

React native: Is it possible to have the height of a html content in a webview?

我从 api 获取 html 内容,我想在我的应用程序中将其呈现为 Web 视图。

webview组件嵌套在一个scrollview中,因为它上面还有一些其他内容我的渲染函数是这样的:

render() {
      var html = '<!DOCTYPE html><html><body>' + this.state.pushEvent.Description + '</body></html>';

    return (
      <ScrollView>
        <View style={styles.recipe}>
          <Image source={{uri: this.state.pushEvent.ImageUrl}}
            style={styles.imgFull} />
          <Text style={styles.title}>{this.state.pushEvent.Title}</Text>
          
          <WebView style={{padding: 20}}
            automaticallyAdjustContentInsets={false}
            scrollEnabled={false}
            html={html}>
          </WebView>
        </View>
      </ScrollView>
    );
  }

问题是我的 html 只是 20pt 高,这是我的填充。有没有什么巧妙的方法来获取内容的高度?

正如我在上面的评论中所写的那样,这就是我得出的结论,但我仍然认为应该有更好的解决方案。

这是 github 上的问题,我的灵感来自:@hedgerwang answer

在我的 var html 中,我在结束 body 标签之前添加了一个简单的脚本,我只是将 html 的高度保存在我的文档标题中:

<script>window.location.hash = 1;document.title = document.height;</script>

然后我在我的 WebView 组件中添加了 onNavigationStateChange 道具,并带有一个设置状态 "height" 变量的回调,然后将此高度设置为我的 WebView。正如我所说,这确实有效,在更改 WebView 中的内容时只需要一点点闪烁,但我认为这是一个肮脏的 hack。

最后我决定更改 api 以包含一些我不必包含在 WebView 中的内容

但也许这会有所帮助,这里是完整的代码。

onNavigationStateChange(navState) {
  this.setState({
    height: navState.title,
  });
}  
render() {
  var html = '<!DOCTYPE html><html><body>' + this.state.pushEvent.Description + '<script>window.location.hash = 1;document.title = document.height;</script></body></html>';
return (
  <ScrollView>
    <View style={styles.recipe}>
      <Image source={{uri: this.state.pushEvent.ImageUrl}}
        style={styles.imgFull} />
      <Text style={styles.title}>{this.state.pushEvent.Title}</Text>

      <WebView style={{padding: 20}}
        automaticallyAdjustContentInsets={false}
        scrollEnabled={false}
        onNavigationStateChange={this.onNavigationStateChange.bind(this)}
        html={html}>
      </WebView>
    </View>
  </ScrollView>
);
}

有更好的方法:您可以使用 injectedJavaScript 属性 注入自定义 JS。评估结果将在您在 onNavigationStateChange 中收到的事件 object 中结束。 这样您就不必修改 HTML 本身或劫持标题 属性.

请参阅 https://gist.github.com/dbasedow/ed6e099823cb8d5ab30e 示例

这个组件非常适合我。它调整 webview 以适应内容和 returns 呈现的高度 html。

https://gist.github.com/epeli/10c77c1710dd137a1335

并改变

import React, {WebView, View, Text} from "react-native";

import React from "react";
import {WebView, View, Text} from "react-native";

在文件的顶部。

唯一可靠的方法是通过 postMessage,在 injectedJavascript 属性中(就像 this component.

通过 document.scrollHeight 就可以了。

const jsString = `
  function post () {
    postMessage(
      Math.max(document.documentElement.clientHeight, document.documentElement.scrollHeight, document.body.clientHeight, document.body.scrollHeight)
    );
  }
  setTimeout(post, 200);
// other custom js you may want
`


// component class:
  _onMessage = (e) => {
    this.setState({
      webviewHeight: parseInt(e.nativeEvent.data)
    });
  }
  render() {
    return (
      <WebView
        source={yourURL}

        injectedJavascript={jsString}
        onMessage={this._onMessage}

        style={{ height: webviewHeight }}
      />
    )
  }

您可以使用 @formidable-webview/webshell 库提供的 HandleHTMLDimensionsFeature。它将使用injectedJavaScript到运行中的一个脚本WebView。 这就是你将如何使用它:

import React from 'react';
import makeWebshell, {
  HandleHTMLDimensionsFeature
} from '@formidable-webview/webshell';
import WebView from 'react-native-webview';

const Webshell = makeWebshell(
  WebView,
  new HandleHTMLDimensionsFeature()
);

export default function AugmentedWebview(props) {
  const onDocumentDimensions = React.useCallback(
    (dimensions) => {
      console.info(dimensions.content);
    },
    []
  );
  return (
    <Webshell
      onDOMHTMLDimensions={onDocumentDimensions}
      {...props}
    />
  );
}

Web 环境 is available here 中的脚本 运行。 每次文档大小发生变化时,都会动态发送尺寸。该脚本将按优先顺序使用 WebView 中可用的最佳 API, ResizeObserver, MutationObserver 最后,定期轮询。如果您正在寻找自动高度 WebViewcheck out this guide.