zoukankan      html  css  js  c++  java
  • React Native 使用 react-native-webview 渲染 HTML

    在 App 中,渲染 html 是一个非常常见的功能,有可能是直接渲染 html 字符串或者是通过 URL 渲染远程 HTML页面。react Native 提供了一个 WebView 组件以供我们实现 HTML 的渲染。

    早先 WebView 是在 react Native 核心包中,后来为了减小 React Native 核心包的体积,便将其单独提出到react-native-webview 组件中。

    话不多说,让我们来试试这个组件吧。

    渲染远程 HTML 内容

    在开始之前,你需要使用 yarn/npm 来安装它:

    yarn add react-native-webview

    安装完成后,我们就可以在代码中使用它:

    import React, { Component } from 'react';
    import { View } from 'react-native';
    import { WebView } from 'react-native-webview';
    
    export default class App extends Component {
      render() {
        return (
          <View>
            <WebView source={{ uri: 'https://www.baidu.com' }} />
          </View>
        )
      }
    }

    需要注意的是:第一次安装完成后,需要重新执行一次 react-native run-* 让 rn 帮我们自动 link 一次,否则会抛出以下错误:

    重新执行 react-native run-* 后,报错没了,但是页面上一片空白。

    这是什么原因呢?在查看了一下文档之后,发现 WebView 默认是不会自动设置其高度,所以这个时候高度是0,我们才无法在页面中找到它。需要注意的是,如果 WebView 的父级组件是 View, 直接使用 style 给 WebView 组件设置高度是无效的,需要给这个 View 组件设置高度才能正常显示。然而在 ScrollView 中,则是需要给 WebView 本身设置 height。其它几个组件,例如 SafeAreaView 我没有去尝试,需要你自己亲自去检验。

    知道原因后,我们将 WebView 父组件设置 style 为 flex: 1 ,让其铺满整个屏幕,在 reload 一次看看效果:

    大功高程,我们已经成功的把百度展现到我们的 App 中了。

    渲染 HTML 字符串

    有时候我们需要将 API 中返回的 HTML 字符串解析出来。渲染 HTML 字符串的时候,我们需要将 source 中的 uri 替换为 html,它的值就是我们的 HTML 字符串。与 uri 不同的是,渲染 HTML 字符串的时候,我们需要设置originWhitelist,比如可以设为["*"]来允许运行本地代码。

    {/* ... */}
    <WebView
      originWhitelist={['*']}
      source={{ html: `<h1>这里是一个标题</h1>` }}
    />
    {/* ... */}

    到这里我们就成功的把标题给渲染出来了。

    根据内容自动计算高度

    往往我们无法提前预知 HTML 内容的高度,所以我们无法给其设置一个固定的高度,而是需要根据内容来设置其高度。

    为了达到这个目的,我们需要用到 injectedJavaScript 和 onMessage ,

    injectedJavaScript

    这个属性的作用是设置一个在网页加载之前执行的 js 代码。

    onMessage

    在 webview 内部的网页中调用 window.postMessage 方法时可以触发此属性对应的函数,从而实现网页和 RN 之间的数据交换。 设置此属性的同时会在 webview 中注入一个 postMessage 的全局函数并覆盖可能已经存在的同名实现。

    网页端的 window.postMessage 只发送一个参数 data,此参数封装在 RN 端的 event 对象中,即 event.nativeEvent.data。data 只能是一个字符串。

    import React, { Component } from 'react';
    import { View, ScrollView, SafeAreaView } from 'react-native';
    import { WebView } from 'react-native-webview';
    
    export default class App extends Component {
      constructor(props) {
        super(props);
    
        this.state = { webViewHeight: 0 };
      }
    
      {/* 根据内容计算 WebView 高度 */}
      onWebViewMessage = (event) => {
        this.setState({ webViewHeight: Number(event.nativeEvent.data) });
      }
    
      render() {
        return (
          <View style={{ flex: 1 }}>
            <View style={{ height: 100, backgroundColor: 'yellow' }}></View>
            <View style={{ height: this.state.webViewHeight }}>
              <WebView
                originWhitelist={['*']}
                source={{ html: `<p>这里是一个标题</p>` }}
                injectedJavaScript='window.ReactNativeWebView.postMessage(document.documentElement.scrollHeight)'
                onMessage={this.onWebViewMessage}
              />
            </View>
            <View style={{ height: 100, backgroundColor: 'green' }}></View>
          </View>
        )
      }
    }

    从上图可以看出我们的 WebView 已经根据其中内容动态的计算了其高度。但是还是有一个问题,这里的文字太小了,要解决这个问题我们需要用到 meta - viewport 。

    广州品牌设计公司https://www.houdianzi.com

    采用响应式布局

    这个其实很简单,只需要在 header 中设置 meta 标签即可。

    <WebView
      originWhitelist={['*']}
      source={{ html: `
      <html>
        <head>
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
        </head>
    
        <body>
          <p>这里是一个标题</p>
        </body>
      </html>
      ` }}
      injectedJavaScript='window.ReactNativeWebView.postMessage(document.documentElement.scrollHeight)'
      onMessage={this.onWebViewMessage}
    />
  • 相关阅读:
    搜广推04-信息检索任务&数据集&LeadBoard&评价指标
    搜广推&NLP03-顶会track记录
    搜广推02-DeepMatch 模型总结[SIGIR2019 tutorial]
    搜广推01-信息检索领域大佬总结
    计算机基础01-终端命令行、VIM、git、CICD
    【python】彼岸图网4K壁纸批量爬虫共1.48G(多线程/多进程)
    【python】不到500行代码实现flappybird小游戏
    解决pyinstaller打包程序太大的问题
    解决pipenv install报错FileNotFoundError: [Errno 2] No such file or directory: ‘d:\miniconda3\Lib\venv
    【python】如何将matplotlib的标题置于图片下方
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/14020584.html
Copyright © 2011-2022 走看看