日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

<label id="nehhv"><address id="nehhv"></address></label><meter id="nehhv"></meter>
  • <pre id="nehhv"></pre>
    學無先后,達者為師

    網站首頁 編程語言 正文

    React?Native?加載H5頁面的實現方法_React

    作者:xiangzhihong8 ? 更新時間: 2022-06-26 編程語言

    一、基本使用

    作為目前流行的移動跨平臺開發技術,React Native 提供了一個使用 JavaScript 構建原生跨平臺移動應用的強大框架。使用React Native開發時,經常會遇到加載H5網頁的需求,此時需要用到react-native-webview插件來執行H5網頁的加載。

    使用插件之前,需要先安裝npm i react-native-webview插件,命令如下:

    npm i react-native-webview
    

    然后,就可以在業務代碼中引入react-native-webview 插件的WebView組件,比如:

    <WebView  ref={ (webView) => this.webView = webView }
              originWhitelist={ ['*'] }
              // 布爾值,指定WebView中是否啟用JavaScript。只在Android上使用,因為在iOS上默認啟用了JavaScript。
              javaScriptEnabled={ true }
              // 布爾值,指定是否開啟DOM本地存儲
              domStorageEnabled={ true }
              // 允許文件上傳
              allowFileAccess={ true }
              // 在webView內部網頁中,調用window.postMessage可以觸發此屬性對應的函數,通過event.nativeEvent.data獲取接收到的數據,實現網頁和RN之間的數據傳遞
              onMessage={ this._onMessage }
              //初始化調用方法
              onLoad={() => { this.handleInjectJavascript();}} 
              // 加載時強制使用loading轉圈視圖,如果為true,webview可能會加載失敗,顯示為空白
              startInLoadingState={false}
              // webview加載錯誤頁面
              renderError={this.renderErrorView}
              // 網絡路徑
              // 也可以為本地路徑 source={ {uri: 'http://192.168.1.1111:8080/'} }
              source={ {uri: 'http://www.baidu.com/'} } />

    使用WebView組件加載H5頁面時,必然會涉及到交互。

    1.1 RN向H5發送數據

    如果是RN向H5發送數據,那么可以調用onLoad函數的handleInjectJavascript() 方法。

     //RN webview 向 vue發送數據
     handleInjectJavascript = (data) => {
         // 拼接數據為方法
         const injectJavascriptStr =  `(function() {
         	window.WebViewBridge.onMessage(${JSON.stringify(data)});
         })()`; 
         // 通過 injectJavaScript  將數據傳遞給WebView頁面,并立即執行為js
         if(this.webView) {
         	this.webView.injectJavaScript(injectJavascriptStr)
         } 
     }

    如果有回調的結果,需要在mounted生命周期函數中,

     mounted() {
        window.WebViewBridge = {
          onMessage: this._onMessage //在window上掛載一個onMessage方法,RN會調用
        }
        // 自定義事件后直接觸發:
        const event = new Event('WebViewBridge')
        window.dispatchEvent(event);
     },
     methods: {
        // 接收 RN 發送的消息
        _onMessage(data) {
          let that = this;
          console.log('data ------- ',JSON.stringify(data)); // 'hello world'
        }
      }
    

    以上就是RN向H5 傳值的過程,其具體過程:RN中給 window.WebViewBridge 增加一個名為 onMessage 的方法,H5初始化頁面會對應給出onMessage 指向的方法,在此代碼塊 指向 _onMessage 方法并執行。

    1.2 H5向RN傳遞數據

    如果是H5頁面主動向RN發送數據,需要用到postMessage方法。

      mounted() {
        // 自定義事件后直接觸發:
        const event = new Event('WebViewBridge');
        window.dispatchEvent(event);
      },
      methods: {
        // 向rn發送消息, 將值 'hello world' 掛載到 postMessage 
        _postMessage('hello world') {
            window.ReactNativeWebView.postMessage(data);
        }
      }
    

    RN 頁面在接收到 vue 傳輸的數據之后執行 onMessage 函數方法。

    onMessage={ this._onMessage }
     _onMessage = (event) => {
            console.log('接收vue發來的消息onMessage', event.nativeEvent.data); 
      }

    1.3 雙向傳值

    當然,有時候,也會涉及到多次雙向傳遞的情況。

      mounted() {
        window.WebViewBridge = {
          onMessage: this._onMessage,
          receiveMessage: this._receiveMessage //在window上掛載一個receiveMessage方法,RN自行調用
        }
        const event = new Event('WebViewBridge')
        window.dispatchEvent(event);
      },
      methods: {
        // 向rn發送消息
        _postMessage('wow,RN!!') {
            window.ReactNativeWebView.postMessage(data);   // 將值 'wow,RN!!' 掛載到 postMessage 
        },
        // 二次或多次接收RN發送消息
         _receiveMessage(data){
          let that = this;
          console.log('data receiveMessage-------  ',JSON.stringify(data));
         }
      }

    RN 頁面在接收到 H5 傳輸的數據之后執行 onMessage 函數。

    onMessage={ this._onMessage }
     // 接受H5發送來的消息
     _onMessage = (event) => {
            console.log('接收H5發來的消息onMessage', event.nativeEvent.data); 
           
            const injectJavascriptStr =  `(function() {
     	   window.WebViewBridge.receiveMessage(${JSON.stringify('hello,vue2!!! ')});
            })()`;
            this.webView.injectJavaScript(injectJavascriptStr);
      }

    二、屬性和方法

    使用 WebView 組件我們可以通過 url 來加載顯示一個網頁,也可以傳入一段 html 代碼來顯示。該組件的引入是解決 React Native 內嵌 H5 的比較好的解決方案,該組件自帶的常用屬性和方法我們可以歸納如下:

    2.1 屬性

    • source:在 WebView 中載入一段靜態的 html 代碼或是一個 url(還可以附帶一些 header 選項)
    • automaticallyAdjustContentInsets:設置是否自動調整內容。格式:boolean
    • contentInset:設置內容所占的尺寸大小。格式為{top:number,left:number,bottom:number,right:number}
    • injectJavaScript:當網頁加載之前注入一段 js 代碼。其值是字符串形式。
    • startInLoadingState:是否開啟頁面加載的狀態,其值為 true 或者 false。
    • bounces(僅iOS):回彈特性。默認為 true。如果設置為 false,則內容拉到底部或者頭部都不回彈。
    • scalesPageToFit(僅iOS):用于設置網頁是否縮放自適應到整個屏幕視圖,以及用戶是否可以改變縮放頁面。
    • scrollEnabled(僅iOS):用于設置是否開啟頁面滾動。
    • domStorageEnabled(僅Android):用于控制是否開啟 DOM Storage(存儲)。
    • javaScriptEnabled(僅Android):是否開啟 JavaScript,在 iOS 中的 WebView 是默認開啟的。

    2.2 方法

    • onNavigationStateChange:當導航狀態發生變化的時候調用。
    • onLoadStart:當網頁開始加載的時候調用。
    • onError:當網頁加載失敗的時候調用。
    • onLoad:當網頁加載結束的時候調用。
    • onLoadEnd:當網頁加載結束調用,不管是成功還是失敗。
    • renderLoading:WebView組件正在渲染頁面時觸發的函數,只有 startInLoadingState 為 true 時該函數才起作用。
    • renderError:監聽渲染頁面出錯的函數。
    • onShouldStartLoadWithRequest(僅iOS):該方法允許攔截 WebView 加載的 URL 地址,進行自定義處理。該方法通過返回 true 或者 false 來決定是否繼續加載該攔截到請求。

    三、使用示例

    3.1 加載外源網頁信息

    import React,{Component} from 'react'
    import {
        StyleSheet,
        View,
        Text,
        WebView,
    } from 'react-native'
    export default class Root extends Component{
        constructor(props){
            super(props)
        }
        render(){
            return (
                <View style={styles.container}>
                    <WebView
                      source={{uri: 'https://www.baidu.com'}}
                        domStorageEnabled={true}
                        javaScriptEnabled={true}
                        startInLoadingState={true}
                        automaticallyAdjustContentInsets={true}>
                    </WebView>
                </View>
            )
        }
    }
    const styles = StyleSheet.create({
        container:{
            flex:1,
        },
    })
    

    上面是一個加載百度首頁的示例。

    3.2 登陸場景

    一款 toB 的 app,面對很多家客戶,每家客戶都有自己的登錄系統界面,并且客戶要求接入自己的登錄系統。這個時候就需要 webview 接入登錄界面之后,進行一些 “值攔截”,進行登錄狀態判斷。這里主要用到 webview 的 onNavigationStateChange 參數。此方法會在當導航狀態發生變化的時候調用,例如取到下面的參數:

       { 
          "canGoBack": false,
          "canGoForward": false, 
          "loading": true,
          "navigationType": "other", 
          "target": 229, 
          "title": "", 
          "url": "https://www.baidu.com/"
       }

    這里主要注意 url 字段,網頁內部登錄完成之后,可以發起一個重定向,前端關注 url 變化,進行登錄狀態的判斷,同時重定向的 url 中可以拼接一些登錄信息字段,用于前端登錄狀態校驗等。

    { "url": "https://www.baidu.com ? sessionId=xxx & username= xxx" }

    3.3 功能模塊嵌入到 RN 中

    將 webview 作為功能模塊載體,這個時候就會涉及到用戶交互,需要 rn 與 h5 進行值的互相傳遞。此時就要react native 向 web 中注入 js,web 也可以主動回傳數據到 react native中。webview 組件提供了 injectedJavaScript 用于向 h5 注入js,在 h5 中使用 window.ReactNativeWebView.postMessage 進行主動的回調,并且在 webview 的 onMessage 中進行字段的監聽,以此就可以完成 react 和 h5 之間的數據交互。

    const injectJSStr = `
      window.injectStr='我是注入的字段';
      var div = document.getElementById('testID');
      div.style.color='red';
      div.style.fontSize='100px';
    `;
    const html = `
        <html>
        <head></head>
        <body>
          <script>
            setTimeout(function () {
              window.ReactNativeWebView.postMessage(window.injectStr)
            }, 2000)
          </script>
          <div id='testID'>Hello Word</div>
        </body>
        </html>
     `;
      ......
    <View style={{flex: 1}}>
        <WebView
            source={{html}}
            injectedJavaScript={injectJSStr}
            onMessage={event => {
            alert(event.nativeEvent.data);
            }}
        />
    </View>
    

    3.4 完整示例

    例如,有下面一個需求:RN里面通過觸發刷新使H5界面的背景色可以隨機改變;H5 界面我們寫一個簡單的 input 輸入使輸入的文字可以在RN 顯示出來。

    import React, {Component} from 'react';
    import {Text, StyleSheet, View, Button} from 'react-native';
    import WebView from 'react-native-webview';
    export default class App extends Component {
      state = {colorIndex: 0, tip: '原生的Text組件,等webview中的發送。。'};
      changeColor = () => {
        this.webview.reload();
        let colorIndex = this.state.colorIndex;
        colorIndex = ++colorIndex % 5;
        this.setState({colorIndex});
      };
      recieve = msg => {
        let data = msg.nativeEvent.data;
        let uname = JSON.parse(data).uname;
        this.setState({tip: uname});
      };
      render() {
        let colors = ['gray', 'yellow', 'red', 'antiquewhite', 'white'];
        let scriptStr = `document.body.style.backgroundColor='${
          colors[this.state.colorIndex]
        }'`;
        return (
          <View style={{flex: 1}}>
            <Button title="刷新WebView的背景色" onPress={this.changeColor} />
            <Text style={{fontSize: 30}}>{this.state.tip}</Text>
            <WebView
              onMessage={this.recieve}
              ref={ref => (this.webview = ref)}
              injectedJavaScript={scriptStr}
              source={{uri: 'http://192.168.180.241:8080/test.html'}}
            />
          </View>
        );
      }
    }
    

    H5的代碼如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <input class="info" name="uname" value="John" />
        <br>
        <button class="info">發送給原生組件</button>
        <script>
            document.querySelector('button').addEventListener('click', () => {
                let uname = document.querySelector('input[name="uname"]').value
                let msg = JSON.stringify({
                    uname
                })
                window.ReactNativeWebView.postMessage(msg)
            })
        </script>
    </body>
    </html>

    原文鏈接:https://blog.csdn.net/xiangzhihong8/article/details/124453363

    欄目分類
    最近更新