react native WebView 高度自适应 RN与网页交互

首先介绍几个属性和方法

1、source

    {uri: string, method: string, headers: object, body: string}, {html: string, baseUrl: string}, number

   在WebView中载入一段静态html代码或者url(还可以附带一些header选项)。

2、injectedJavaScript 

    设置在网页加载之前注入的一段JS代码。

3、onMessage

    在webview内部的网页中调用window.postMessage方法时可以触发此属性对应的函数,从而实现网页和RN之间的数据交换。

设置此属性的同时会在webview中注入一个postMessage的全局函数并覆盖可能已经存在的同名实现。

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

4、onLoadEnd

    加载结束时(无论成功或失败)调用。 

一、高度自适应

例子:

第一种方法:

    首先要在初始化阶段定义初始高度,如果webview的style属性中没有设置高度,内容会不显示。

  constructor(props) {
    super(props);
    this.state = {
      WebViewHeight: 100,
    };
  }
    要显示的html内容
        let html = `<!DOCTYPE html> <html lang="en"> 
            <head>
              <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <style>
              </style>
            </head> 
            <body>一些html标签及内容
            <script>
            window.onload = function () {
              window.location.hash = 1;
              document.title = document.body.clientHeight;
            }
            </script></body>  </html>` 
在html的script中获取高度,在WebView的 onNavigationStateChange 函数里设置高度
        <WebView
                ref={'webview'}
                source={{ html: html }}
                style={{ height: this.state.WebViewHeight }}
                onNavigationStateChange={(title)=>{
                  this.setState({
                    WebViewHeight: parseInt(title.title) || 200
                  })
                }}
              />         

上面这种方法我在Android手机中有时获取不到高度

第二种方法:
在url加载结束后,注入一段js代码,用来获取url网页的高度,然后通过与RN交互的方式,把获取的高度通过window.postMessage传回RN中,然后显示
          <WebView
              ref={'webview'}
              style={{ height: this.state.WebViewHeight }}
              source={{ uri: 'https://mp.weixin.qq.com/s/ErAMhnlFXAxyLYOBhl4OTA' }}
              onLoadEnd={this.webViewLoaded}
              onMessage={(e) => {
                this.handleMessage(e)
              }}
              javaScriptEnabled={true}
            />
      webViewLoaded = () => {
          this.refs.webview.injectJavaScript(`
              const height = document.body.scrollHeight;
              window.postMessage(height);
          `);
        }
      handleMessage(e) {
        this.setState({
          WebViewHeight: e.nativeEvent.data
        });
      }

二、RN与网页交互

1、网页向RN发送数据
首先在html的script定义一个发送数据的方法
let html = `<!DOCTYPE html> <html lang="en"> 
            <head>
              <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
              <style>
                button: {
                   color: blue;
                }
              </style>
            </head> 
            <body>一些html标签及内容<button>按钮</button>
            <script>
                function sendData(data) {
                    if (window.originalPostMessage) {
                      window.postMessage(data);
                    } else {
                      throw Error('postMessage接口还未注入');
                    }
                  }
                document.getElementById('button').onclick = function() {
                    sendData('网页向RN发送数据');
                }
            </script>
            </body> 
            </html>`
<WebView
  ref={'webview'}
  source={{html: html}}
  style={{width: 300, height: 300}}
  onMessage={(e) => {
    this.handleMessage(e)
  }}
/>

在RN中也handleMessage为接收数据的方法,e.nativeEvent.data就是从网页html中传过来的数据

handleMessage(e) {
  console.log(e.nativeEvent.data)
}
2、RN网页发送数据

首先定义一个发送数据的方法

sendMessage() {
  this.refs.webview.postMessage('RN向网页发送数据');
}
在html中也要有相应的接收数据的方法
window.onload = function () {
  document.addEventListener('message', function (e) {
    document.getElementById('button').textContent = e.data;
  });
}

以上

猜你喜欢

转载自blog.csdn.net/Lee_taotao/article/details/80620737
今日推荐