網站首頁 編程語言 正文
一、基本使用
作為目前流行的移動跨平臺開發技術,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
相關推薦
- 2022-08-28 Go通道channel通過通信共享內存_Golang
- 2023-01-23 Python操作MongoDB增刪改查代碼示例_python
- 2022-11-23 詳解Android消息機制完整的執行流程_Android
- 2022-11-22 Nginx?Tomcat負載均衡動靜分離原理解析_nginx
- 2023-05-10 python中使用numpy包的向量矩陣相乘np.dot和np.matmul實現_python
- 2022-03-18 docker?創建容器時指定容器ip的實現示例_docker
- 2022-07-04 C語言植物大戰數據結構堆排序圖文示例_C 語言
- 2022-05-02 在kali上安裝AWVS的圖文教程_相關技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支