React Native之網頁組件WebView的使用與通信


在實際開發中,我們通常會嵌入一些html頁面,官方為我們提供了一個非常好用的網頁組件WebView,通過這個組件我們可以通過傳入一個url或者是傳入一段html

一. WebView的基本屬性方法介紹與使用

主要屬性介紹

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

主要方法介紹

  • onNavigationStateChange:當導航狀態發生變化的時候調用。
  • onLoadStart:當網頁開始加載的時候調用。
  • onError:當網頁加載失敗的時候調用。
  • onLoad:當網頁加載結束的時候調用。
  • onLoadEnd:當網頁加載結束調用,不管是成功還是失敗。
  • renderLoading:WebView組件正在渲染頁面時觸發的函數,只有 startInLoadingState 為 true 時該函數才起作用。
  • renderError:監聽渲染頁面出錯的函數。
  • onShouldStartLoadWithRequest(僅iOS):該方法允許攔截 WebView 加載的 URL 地址,進行自定義處理。該方法通過返回 true 或者 falase 來決定是否繼續加載該攔截到請求。
  • onMessage:在webView內部網頁中,調用window.postMessage可以觸發此屬性對應的函數,通過event.nativeEvent.data獲取接收到的數據,實現網頁和RN之間的數據傳遞
  • injectJavaScript(function):函數接受一個字符串,該字符串將傳遞給WebView,並立即執行為JavaScript。

通過url加載一個頁面

        render() {
		return (
			<View style={styles.container}>
				<WebView
					ref={webView => this.webView = webView}
					startInLoadingState={true}
					onNavigationStateChange={e => this.onNavigationStateChange(e)}
					source={{ uri: 'https://github.com/xxxxxxx'}}
				/>
			</View>
		);
	}

通過html加載一個頁面

        render() {
		return (
			<View style={styles.container}>
				<WebView
					ref={webView => this.webView = webView}
					startInLoadingState={true}
					onNavigationStateChange={e => this.onNavigationStateChange(e)}
					source={{ html: '<h1'>Demo</h1>'}}
				/>
			</View>
		);
	}

二. RN WebView和H5之間的通信

1.RN WebView向H5頁面注入JS

思路: 通過jnjectedJavaScript的方式注入JS,在H5頁面加載之后立即執行。(可以理解為是在WebView中去主動觸發H5的方法,從而實現通信)

需要注意的是,injectedJavaScript注入的必須是JS,注入的內容可以是方法的實現也可以是方法名。其實注入函數名的時候,實際上注入的仍然是函數的實現。當注入js方法名需要傳遞參數的時候,可以提前將函數名作為字符串,函數參數作為變量,通過生成一個字符串然后再講字符串注入。

render() {
        let text = 'back';
        let call = `call('${text}')`;
        return (
            <View
                style={{flex: 1, backgroundColor: 'white', marginBottom: SAFE_AREA_BOTTOM_HEIGHT}}>
                <WebView style={{flex: 1}}
                         ref='webView'
                         injectedJavaScript={`${text1}`}
                         source={{
                             html: '<body>\n' +
                             '<button onClick="call()" style="margin-top: 100px;" id="call">call</button>\n' +
                             '<script>\n' +
                             '    function call(text) {\n' +
                             '        var btn=  document.getElementById(\'call\')\n' +
                             '        btn.innerHTML="text";\n' +
                             '    }\n' +
                             '\n' +
                             '</script>\n' +
                             '</body>'       
                >
                </WebView>
            </View>
        );
    }

上述代碼當通過WebView向RN頁面注入一個html代碼的時候,通過injectedJavaScript向H5通信,然后更改button的名字。

2.WebView和H5相互發送監聽消息

該方式可以雙向發送消息

2.1 RN端向H5發送消息

WebView綁定ref,通過html5新增的postMessage發送消息

onLoadEnd={() => {
     this.refs.webView.postMessage('RN向H5發送的消息');
 }}

在H5中注冊監聽

window.onload = function() {
     document.addEventListener('message', function(msg) {
       console.log(msg)
       message = msg.data;
   });
 }

2.2 H5向RN發送消息

在RN端通過onMessage接收消息

onMessage={(event) => {console.log(event.nativeEvent.data);}}

網頁端的 window.postMessage 只發送一個參數 data,此參數封裝在 RN 端的 event 對象中,即 event.nativeEvent.data。data 只能是一個字符串。

H5發送消息,此時只能傳遞string類型

window.postMessage('網頁向rn發送的消息');


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM