ReactNative WebView組件詳解


在開發Android的時候,一般我們會有一些加載網頁的需求,或者執行一些JavaScript,我們都知道在Android中實現這個功能的控件是WebView,在ReactNative中也有實現此類需求額的組件,它的名字也是WebView。那么今天的這篇文章就來詳細說說在ReactNative WebView的使用。本文示例效果圖

webview.gif

屬性

  • automaticallyAdjustContentInsets
    控制是否調整放置在導航條、標簽欄或工具欄后面的web視圖的內容。默認值為true

  • contentInset {top: number, left: number, bottom: number, right: number}
    設置網頁內嵌邊距

  • injectedJavaScript
    設置在網頁加載之前注入一段js代碼

  • mediaPlaybackRequiresUserAction
    設置頁面中的HTML5音視頻是否需要在用戶點擊后再開始播放。默認值為true

  • scalesPageToFit
    設置是否要把網頁縮放到適應視圖的大小,以及是否允許用戶改變縮放比例。

  • source
    在WebView中指定加載內容html或者url,可以指定header,method等

  • startInLoadingState
    強制WebView在第一次加載時先顯示loading視圖。默認為true

  • domStorageEnabled(android)
    布爾值,指定是否開啟DOM本地存儲

  • javaScriptEnabled(android)
    布爾值,指定WebView中是否啟用JavaScript。只在Android上使用,因為在iOS上默認啟用了JavaScript。

  • mixedContentMode(android)
    指定混合內容模式。即WebView是否應該允許安全鏈接(https)頁面中加載非安全鏈接(http)的內容,

    • 'never' (默認) - WebView不允許安全鏈接頁面中加載非安全鏈接的內容
    • 'always' - WebView允許安全鏈接頁面中加載非安全鏈接的內容。
    • 'compatibility' - WebView會盡量和瀏覽器當前對待此情況的行為一致
  • userAgent(android)
    為WebView設置user-agent字符串標識。這一字符串也可以在原生端用WebViewConfig來設置,但js端的設置會覆蓋原生端的設置。

  • allowsInlineMediaPlayback(ios)
    指定HTML5視頻是在網頁當前位置播放還是使用原生的全屏播放器播放。 默認值為false,視頻在網頁播放還需要設置webkit-playsinline

  • bounces(ios)
    指定滑動到邊緣后是否有回彈效果。

  • decelerationRate(ios)
    指定一個浮點數,用於設置在用戶停止觸摸之后,此視圖應以多快的速度停止滾動。也可以指定預設的字符串值,如"normal"和"fast",

  • scrollEnabled(ios)
    是否啟用滾動

函數

  • injectJavaScript
    函數接受一個字符串,該字符串將傳遞給WebView,並立即執行為JavaScript
  • onError
    加載失敗時回調
  • onLoad
    完成加載時回調
  • onLoadEnd
    加載成功或者失敗都會回調
  • onLoadStart
    開始加載的時候回調
  • onMessage
    在webView內部網頁中,調用window.postMessage可以觸發此屬性對應的函數,通過event.nativeEvent.data獲取接收到的數據,實現網頁和RN之間的數據傳遞
  • renderError
    返回一個視圖用來提示用戶錯誤
  • renderLoading
    返回一個加載指示器
  • onShouldStartLoadWithRequest(ios)
    請求自定義處理,返回true或false表示是否要繼續執行響應的請求

實戰分析

通過上面的介紹,我們已經對組件的屬性以及函數有了大致的了解,當然只有這些是不夠的,接下來就該組件的使用展開分析,效果圖如文章開頭的GIF圖。對於該組件最簡單的使用如下

  1.  
    <WebView
  2.  
    source={{uri:'http://www.jianshu.com/u/d5b531888b2b'}}
  3.  
    style={{width: '100%',height:'100%'}}
  4.  
    />

指定source屬性,加載網頁,設置寬和高全屏,需要注意的是必須指定寬和高,否則將不顯示組件,默認寬高都是0。
給WebView增加加載時的回調

  1.  
    onLoad={(e) => console.log('onLoad')}
  2.  
    onLoadEnd={(e) => console.log('onLoadEnd')}
  3.  
    onLoadStart={(e) => console.log('onLoadStart')}
  4.  
    renderError={() => {
  5.  
    console.log('renderError')
  6.  
    return <View><Text>renderError回調了,出現錯誤</Text></View>
  7.  
    }}
  8.  
    renderLoading={() => {
  9.  
    return <View><Text>這是自定義Loading...</Text></View>
  10.  
    }}

renderError可以自定義加載錯誤的提示信息View.當加載錯誤時會回調該函數,並且顯示該函數返回的View。使用此方法我們可以自定義加載錯誤時的提示信息。
而renderLoading函數可以自定義加載提示.當我們通過WebView加載一個網頁時,往往我們有需求展示出請求的url,網頁的標題,以及是否可前進或者后退。在WebView組件中有一個函數onNavigationStateChange可以實現此功能,他是在加載開始和結束的時候回調的,

  1.  
    //添加屬性
  2.  
    onNavigationStateChange={ this._onNavigationStateChange}
  3.  
     
  4.  
    _onNavigationStateChange = (navState) => {
  5.  
    console.log(navState)
  6.  
    this.setState({
  7.  
    backButtonEnabled: navState.canGoBack,
  8.  
    forwardButtonEnabled: navState.canGoForward,
  9.  
    url: navState.url,
  10.  
    status: navState.title,
  11.  
    loading: navState.loading,
  12.  
    });
  13.  
    }

當canGoBack返回值為true時,我們就可以使用this.webview.goBack();(this.webview是WebView的引用)對網頁進行回退操作,同理當canGoForward為true時我們就可以使用 this.webview.goForward();對我們的網頁進行跳轉操作。當我們的網頁url發生改變時我們可以使用 this.webview.reload();加載新的網頁。

加載HTML

  1.  
    <WebView>
  2.  
    style={{width: '100%',height:'100%'}}
  3.  
    source={ require('./helloworld.html');}
  4.  
    </WebView>

RN和Html通信

當WebView加載html時我們可以實現html和rn之間的通信。rn向html發生數據可以通過postMessage函數實現。如下

  1.  
    this.webview.postMessage('"Hello" 我是RN發送過來的數據');
  2.  
    //在html中注冊事件接收rn發過來的數據並顯示在html中
  3.  
    document.addEventListener('message', function(e) {
  4.  
    messagesReceivedFromReactNative += 1;
  5.  
    document.getElementsByTagName('p')[0].innerHTML =
  6.  
    '從React Native接收的消息: ' + messagesReceivedFromReactNative;
  7.  
    document.getElementsByTagName('p')[1].innerHTML = e.data;
  8.  
    });
  9.  
     

在html中我們定義了一個按鈕,並添加事件向rn發送數據

  1.  
    //window.postMessage向rn發送數據
  2.  
    document.getElementsByTagName('button')[0].addEventListener('click', function() {
  3.  
    window.postMessage('這是html發送到RN的消息');
  4.  
    });

當html中調用了window.postMessage函數后,WebView的onMessage函數將會被回調,用來處理html向rn發送的數據,可以通過e.nativeEvent.data獲取發送過來的數據。

  1.  
    //接收HTML發出的數據
  2.  
    _onMessage = (e) => {
  3.  
    this.setState({
  4.  
    messagesReceivedFromWebView: this.state.messagesReceivedFromWebView + 1,
  5.  
    message: e.nativeEvent. data,
  6.  
    })
  7.  
    Alert.alert(e.nativeEvent. data)
  8.  
    }

JavaScript

在android這個需要使用 javaScriptEnabled屬性來支持JavaScript,ios默認是支持的,沒有此屬性。在WebView中提供了函數injectJavaScript(String),它有一個字符串參數,可以向webview中注入腳本,如下

  1.  
    //腳本注入
  2.  
    injectJS = () => {
  3.  
    const script = 'document.write("Injected JS ")'; // eslint-disable-line quotes
  4.  
    if (this.webview) {
  5.  
    this.webview.injectJavaScript(script);
  6.  
    }
  7.  
    }

最后需要注意的一點,ScrollView中嵌套WebView時滑倒會有沖突,需要特殊處理(目前還沒研究處理方法。)今天的這篇文章就介紹這么多,所介紹的實例中,只提供了核心代碼,如果想查看全部代碼可以訪問GitHub,由於認知有限,若有錯誤的地方歡迎指出,共同進步,謝謝。

最后補充:

ReactNative WebView實現Android端圖片和視頻的拍攝和選擇,以及ios,android根據webView內容自動設置高度(WebView嵌套在ScrollView中問題),修復現在Android端WebView偶先的閃退bug,插件地址https://github.com/xiehui999/react-native-webview-plugin.git


免責聲明!

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



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