react-native WebVIew消息傳遞

onMessage
在 webview 內(nèi)部的網(wǎng)頁(yè)中調(diào)用 window.postMessage 方法時(shí)可以觸發(fā)此屬性對(duì)應(yīng)的函數(shù),從而實(shí)現(xiàn)網(wǎng)頁(yè)和 RN 之間的數(shù)據(jù)交換。 設(shè)置此屬性的同時(shí)會(huì)在 webview 中注入一個(gè) postMessage 的全局函數(shù)并覆蓋可能已經(jīng)存在的同名實(shí)現(xiàn)。

網(wǎng)頁(yè)端的 window.postMessage 只發(fā)送一個(gè)參數(shù) data,此參數(shù)封裝在 RN 端的 event 對(duì)象中,即 event.nativeEvent.data。data 只能是一個(gè)字符串。

類(lèi)型 必填
function 否
我們直接調(diào)用postMessage會(huì)發(fā)現(xiàn)h5中消息不能傳遞給RN,這是由于版本升級(jí),導(dǎo)致老的api調(diào)用的時(shí)候會(huì)出現(xiàn)一些問(wèn)題,在github上的issue里有的說(shuō)在setTimeout的回調(diào)函數(shù)中使用postMessage方法可以傳遞消息,但是自己親測(cè)這樣做沒(méi)有作用,然后在新文檔的issue中找到下面這樣的一個(gè)回復(fù),成功解決了問(wèn)題

image.png

安卓端webview使用本地文件路徑如下:
。。。AwesomeProject\android\app\src\main目錄下新建一個(gè)assets目錄,里面存放h5代碼,source中的引用路徑為:file:///android_asset/h5/index.html
在ios平臺(tái)上,引用本地的h5可以在項(xiàng)目src文件夾下建相關(guān)目錄,使用require('相對(duì)路徑')的方式引入
簡(jiǎn)單示例代碼如下:
h5:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./build/calendar.css">
    <style>
        .btn{
            background: #f00;color:#fff
        }
    </style>
</head>
<body style="background:#ddd;">
    <div style="text-align: center">
        <button id="button" onclick="send()">發(fā)送數(shù)據(jù)到react native</button>
        <p style="text-align: center">收到react native發(fā)送的數(shù)據(jù): <span id="data"></span></p>
    </div>
</body>
<script>
    var data = 0;
    function send () {
        data += 100;
        window.ReactNativeWebView.postMessage("Hello React");
    }
    window.onload = function () {
        document.addEventListener('message', function (e) {
            document.getElementById('data').textContent = e.data;
        });
    }
</script>
</html>

RN:

import React from 'react'
import {View, Button, Text, AsyncStorage} from 'react-native'
import {WebView} from 'react-native-webview'
import {decrement, increment} from "../../store/action";
import { SwitchActions } from "react-navigation";

class HomeScreen extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            webViewData: 0
        }
        this.data = 0
    }
    sendMessage() {
        this.refs.webview.postMessage(++this.data);
    }
    handleMessage(e) {
        this.setState({webViewData: e.nativeEvent.data});
    }
    render() {
        return (
            <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
                <WebView
                ref={'webview'}
                source={{uri: 'file:///android_asset/h5/index.html'}}
                style={{width:375, height:120, backgroundColor: '#eee'}}
                onMessage={(event) => {
                    // alert(e.nativeEvent.data)
                    console.log(event.nativeEvent)
                    this.handleMessage(event)
                }}/>
                <Text>來(lái)自webview的數(shù)據(jù) : {this.state.webViewData}</Text>
                <Text onPress={() => {
                    this.sendMessage()
                }}>發(fā)送數(shù)據(jù)到WebView</Text>
            </View>
        )
    }
}

export default HomeScreen
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容