react-native 與HTML交互

使用框架 react-native-webview

安裝 react-native-webview

yarn add react-native-webview

在放在根目錄下,創(chuàng)建一個(gè).bundle文件羊初,將html酸役、靜態(tài)資源癣漆、css放到bundle里面如圖


截屏2022-10-24 14.41.03.png
截屏2022-10-24 14.41.15.png

1.引入

import WebView from 'react-native-webview'

2.創(chuàng)建web 增加屬性 originWhitelist={['*']}//解決iOS無法打開bundle里面的html問題 中文亂碼顯示的問題
onMessage 接受來自HTML的消息
使用this.webview.postMessage(JSON.stringify(data))給HTML發(fā)送消息

render() {
        let source = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + `Static.bundle/index.html`;
        return (
            <WebView
                // source={require('../../Static.bundle/index.html')}
                source={{ uri: source }}
                // source={{uri:'https://m.baidu.com'}}
                style={styles.container}
                onLoad={() => {
                    console.log('webview onLoad')
                }}
                onLoadEnd={() => {
                    console.log('webview onLoadEnd')
                }}
                onLoadStart={() => {
                    console.log('wenview onLoadStart')
                }}
                onMessage={event => {
                    console.log('===>接收到的消息', event.nativeEvent.data)
                    this.onMessageHandle(event.nativeEvent.data)
                    // 發(fā)送消息給HTML
                    this.sendMessageToHtml(event.nativeEvent.data)
                }}
                originWhitelist={['*']}//解決iOS無法打開bundle里面的html問題 中文亂碼顯示的問題
                javaScriptEnabled={true}
                ref={webview => this.webview = webview}

            />
        )
    }
}

3.html改造
在js里面增加方法,使用此方法向react-native傳遞消息

 window.ReactNativeWebView.postMessage()

接收來react-native的數(shù)據(jù) 最好兩個(gè)都寫上

window.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)

        const message = e.data;//字符串類型

        console.log('WebView message:', message);

        alert(message);

    })
    document.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)

        const message = e.data;//字符串類型

        console.log('WebView message:', message);

        alert(message);

    })

完整react代碼

import React, { Component } from 'react'
import { StyleSheet, Dimensions, NativeModules, NativeEventEmitter,Alert } from 'react-native'
import WebView from 'react-native-webview'
const CalendarManager = NativeModules.CalendarManager
//接收來自原生app的消息
const calendarManagerEmitter = new NativeEventEmitter(CalendarManager);
const subscription = calendarManagerEmitter.addListener(
    'EventReminder',
    (reminder) => {
        console.log("===>接收到來自原生app的消息", reminder.name),
        Alert.alert(reminder.name)
    }

);
export default class MyWebview extends Component {
    constructor() {
        super()
        // this.sendMessageToHtml = this.sendMessageToHtml.bind(this)
    }
    // sendMessageToHtml = (data)=>{
    //     setTimeout(() => {
    //         console.log('===>需要傳送的data',data)
    //         this.webview.postMessage(JSON.stringify(data))   
    //     }, 2000);
    // }
    // onMessageHandle =(data)=>{
    //     console.log('===>',data)
    //     let obj = JSON.parse(data)
    //     console.log('===>obj',obj)
    //     if(obj.home === 'userCamara'){
    //         this.props.navigation.navigate('swiper')
    //     }
    // }
    //發(fā)送消息給HTML
    sendMessageToHtml = (data) => {

        setTimeout(() => {
            console.log('===>需要傳送的data', data)
            this.webview.postMessage(JSON.stringify(data))   
        }, 2000);
    }
    //HTML 向 react-native發(fā)送消息
    onMessageHandle = (data) => {
        console.log('===>', data)
        let obj = JSON.parse(data)
        console.log('===>obj', obj)
        // if(obj.home === 'userCamara'){
        if (obj.type === '0') {
            this.props.navigation.navigate(obj.home)
        } else {
            console.log('===>type', obj.type)
            this.sendMessageToOC(obj)
        }

        // }
    }
    //發(fā)消息給OC
    sendMessageToOC = (data) => {
        CalendarManager.addDic('生日派對(duì)',
            data,
            (error, events) => {
                if (error) {
                    // alert(error)
                } else {
                    // alert(events)
                }

            }

        )
    }

    render() {
        let source = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + `Static.bundle/index.html`;
        return (
            <WebView
                // source={require('../../Static.bundle/index.html')}
                source={{ uri: source }}
                // source={{uri:'https://m.baidu.com'}}
                style={styles.container}
                onLoad={() => {
                    console.log('webview onLoad')
                }}
                onLoadEnd={() => {
                    console.log('webview onLoadEnd')
                }}
                onLoadStart={() => {
                    console.log('wenview onLoadStart')
                }}
                onMessage={event => {
                    console.log('===>接收到的消息', event.nativeEvent.data)
                    this.onMessageHandle(event.nativeEvent.data)
                    this.sendMessageToHtml(event.nativeEvent.data)
                }}
                originWhitelist={['*']}//解決iOS無法打開bundle里面的html問題 中文亂碼顯示的問題
                javaScriptEnabled={true}
                ref={webview => this.webview = webview}

            />
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        width: Dimensions.get('window').width,
        height: Dimensions.get('window').height
    }
})

html代碼

<!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>
    <link rel='stylesheet' type="text/css" href="./html.css" />
    <link rel='stylesheet' type='text/css' href="./iconfont.css">
</head>

<body>
    <div class="bodyContainer">

        <!-- <h1>測(cè)試demo</h1> -->

        <div id="container" class="itemContainer">
            <!-- <div class="itemStyles" onclick="onclick1(this,'camera')">
                <img src="./images/xiangce.png" alt="" width="80px" height="80px" />
                <div>調(diào)起相機(jī)</div>
            </div> -->
        </div>
        <script>
            const imageArray = [
                {
                    imageName: './images/xiangji1fill.png',
                    title: '調(diào)用相機(jī)',
                    stackName: 'camera',
                    type:'0',

                },
                {
                    imageName: './images/shouyelunbotu.png',
                    title: '輪播圖',
                    stackName: 'swiper',
                    type:'0',
                },
                {
                    imageName: './images/save-s.png',
                    title: '本地存儲(chǔ)',
                    stackName: 'localAysncStorage',
                    type:'0',
                },
                {
                    imageName: './images/wangyesheji.png',
                    title: '加載網(wǎng)頁',
                    stackName: 'webview',
                    type:'0',
                },
                {
                    imageName: './images/xiangce.png',
                    title: '選擇圖片',
                    stackName: 'pickerImage',
                    type:'0',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '獲取定位',
                    stackName: 'location',
                    type:'0',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '百度OCR',
                    stackName: 'calendar',
                    type:'1',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '指紋鎖',
                    stackName: 'calendar',
                    type:'2',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '基座版本',
                    stackName: 'calendar',
                    type:'3',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '設(shè)備信息',
                    stackName: 'calendar',
                    type:'4',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '狀態(tài)欄高度',
                    stackName: 'calendar',
                    type:'5',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '開始采集語音',
                    stackName: 'calendar',
                    type:'6',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '采集語音',
                    stackName: 'calendar',
                    type:'7',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '二維碼',
                    stackName: 'calendar',
                    type:'8',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '注冊(cè)人臉',
                    stackName: 'calendar',
                    type:'9',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '驗(yàn)證人臉',
                    stackName: 'calendar',
                    type:'10',
                },
                {
                    imageName: './images/dingwei.png',
                    title: '刪除人臉',
                    stackName: 'calendar',
                    type:'11',
                },
            ]
            var htmlElements = "";
            console.log('===>', imageArray.length)
            for (var i = 0; i < imageArray.length; i++) {
                let item = imageArray[i]
                console.log('===>', item.title, item)
                htmlElements += `<div id='container'><div class='itemStyles' onclick="onclick1(this,'${item.stackName}','${item.type}')"><img src='${item.imageName}' alt='' width='45px' height='45px' /><div>${item.title}</div></div></div>`;
            }
            var container = document.getElementById("container");
            container.innerHTML = htmlElements;
        </script>


    </div>

</body>

</html>
<script>
    onclick1 = (obj, stackName,type) => {
        console.log(obj, stackName ,type)
        window.ReactNativeWebView.postMessage(JSON.stringify({
            home: stackName,
            type:type
        }));
    }
    window.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)

        const message = e.data;//字符串類型

        console.log('WebView message:', message);

        alert(message);

    })
    document.addEventListener('message', function (e) {//注冊(cè)事件 接收數(shù)據(jù)

        const message = e.data;//字符串類型

        console.log('WebView message:', message);

        alert(message);

    })
    function jsToOC(name) {
        window.webkit.messageHandlers.jsToOC.postMessage({"params":name});
    }
</script>

css

  
.bodyContainer{
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
.itemContainer{
    display: flex;
    flex-direction: row;
    justify-content: start;
    flex-wrap: wrap;
}
.itemStyles{
    display: flex;
    flex-direction: column;
    width: 23vw;
    height: 110px;
    justify-content: center;
    align-items: center;
    text-align: center;
    font-size: 12px;
}

react-native 與原生OC的交互:http://www.reibang.com/p/5a5d3995ae31

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市渠啤,隨后出現(xiàn)的幾起案子狐肢,更是在濱河造成了極大的恐慌,老刑警劉巖沥曹,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件份名,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡妓美,警方通過查閱死者的電腦和手機(jī)僵腺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來部脚,“玉大人想邦,你說我怎么就攤上這事∥酰” “怎么了丧没?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)锡移。 經(jīng)常有香客問我呕童,道長(zhǎng),這世上最難降的妖魔是什么淆珊? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任夺饲,我火速辦了婚禮,結(jié)果婚禮上施符,老公的妹妹穿的比我還像新娘往声。我一直安慰自己,他們只是感情好戳吝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布浩销。 她就那樣靜靜地躺著,像睡著了一般听哭。 火紅的嫁衣襯著肌膚如雪慢洋。 梳的紋絲不亂的頭發(fā)上塘雳,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音普筹,去河邊找鬼败明。 笑死,一個(gè)胖子當(dāng)著我的面吹牛太防,可吹牛的內(nèi)容都是我干的妻顶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼杏头,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼盈包!你這毒婦竟也來了沸呐?” 一聲冷哼從身側(cè)響起醇王,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎崭添,沒想到半個(gè)月后寓娩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呼渣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年棘伴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屁置。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡焊夸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蓝角,到底是詐尸還是另有隱情阱穗,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布使鹅,位于F島的核電站揪阶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏患朱。R本人自食惡果不足惜鲁僚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裁厅。 院中可真熱鬧冰沙,春花似錦、人聲如沸执虹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽声畏。三九已至撞叽,卻和暖如春姻成,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愿棋。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工科展, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糠雨。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓才睹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親甘邀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子琅攘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容