【5+】Webview页面之间的数据交流

一个App,其中大部分是要对页面之间的数据进行交互。
1DBFB83E6BDA9816D35E4796DE55BB0B

碧如:A打开B页面,B页面执行一些代码,再通知回A页面。

这可能是h5+er们遇到最常见的一个场景了。

ok,我们将问题实例化:

A页面有个选择地区的按钮,需要打开B页面选择一个地区,然后获取到选取结果返回给A页面并展示。

我们看看用mui.fire怎么来实现这个功能

e9fbd9d5a31f5e16

A页面

clipboard.png

        <header class="mui-bar mui-bar-nav">
            <h1 class="mui-title">A</h1>
        </header>
        <div class="mui-content">
            <input type="text" readonly placeholder="未选择">
            <button type="button" class="mui-btn mui-btn-blue">选取地区</button>
        </div>
        
        <script src="js/mui.min.js"></script>
        <script type="text/javascript">
            mui.init();
            // 自定义监听select事件
            document.addEventListener('select', function(e){
                var text = e.detail.text;
                document.querySelector("input").value = text;
            });
            // 按钮点击事件
            document.querySelector(".mui-btn-blue").addEventListener('tap', function(){
                // 打开B页面,选取一个结果
                mui.openWindow('B.html');
            });
        </script>

B页面

clipboard.png

        <header class="mui-bar mui-bar-nav">
            <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>
            <h1 class="mui-title">B</h1>
        </header>
        <div class="mui-content">
            <ul class="mui-table-view">
                <li class="mui-table-view-cell">
                    <a class="mui-navigate-right">
                        上海
                    </a>
                </li>
                <li class="mui-table-view-cell">
                    <a class="mui-navigate-right">
                        深圳
                    </a>
                </li>
                <li class="mui-table-view-cell">
                    <a class="mui-navigate-right">
                        北京
                    </a>
                </li>
            </ul>
        </div>

        <script src="js/mui.min.js"></script>
        <script type="text/javascript">
            mui.init();
            mui('ul').on('tap', 'li', function() {
                // 获取当前选择的内容
                var text = this.innerText;
                // 通知上个页面
                var w = plus.webview.currentWebview();
                var opener = w.opener();
                mui.fire(opener, "select",{
                    text: text
                });
                // 关闭本页面
                w.close();
            });

真机调试一下,o98k。

clipboard.png

但是!我个人还是建议脱离mui.js来实现这个功能

clipboard.png

可以借用咱们之前文章里面的讲过的,利用webview对象的evalJS方法

【5+】跨webview多页面 触发事件(一)
【5+】跨webview多页面 触发事件(一)

感觉用Broadcast.js有点小题大做

clipboard.png

那咱们就写一个类似Android中的onActivityResult和setResult方法

新建一个app.js,作为一个自己的插件,里面实现两个方法 onActivityResult 和 setResult


(function(app){
    
    /**
     * 打开一个页面
     * @param {String} url 页面路径
     * @param {String} id 页面id
     * @param {Object} ex 参数
     * @param {Function} callback 
     */
    app.onActivityResult = function(url, id, ex, callback){
        
    };
    
    /**
     * 返回创建者页面数据
     * @param {Object} data 需要返回的数据
     * @return {Webview} w 当前webview
     */
    app.setResult = function(data){
        
    };
    
    
}(window.app || (window.app = {})));

我们一步步来,先看看setResult如何触发上个页面的函数

    /**
     * 返回创建者页面数据
     * @param {Object} data 需要返回的数据
     * @return {Webview} w 当前webview
     */
    app.setResult = function(data){
        // 获取当前webview
        var indexW = plus.webview.currentWebview();
        // 获取创建者的webview
        var opener = indexW.opener();
        // 执行js字符串
        opener.evalJS();// ??????
    };

卧槽,那么,问题来了,evalJS该执行什么呢?

如果我在A页面的window对象下定一个函数

window.test = function(data){
    alert(JSON.stringify(data));
}

那么,我们在evalJS里面就该这么写

        // 执行js字符串
        var jsstr = "window.test && window.test(" + JSON.stringify(data) + ")";
        opener.evalJS(jsstr); 

好吧,考虑到一个页面可能通过这个方式打开多个页面,那么我们这个test函数就得改一个不重复唯一的名称,并且定义放到onActivityResult方法里面

    var _id = 0,
        _tempName = '',
        ow,cw;

        /**
         * 打开一个页面
         * @param {String} url 页面路径
         * @param {String} id 页面id
         * @param {Object} ex 参数
         * @param {Function} callback 
         */
        app.onActivityResult = function(url, id, ex, callback) {
            
            // 生成唯一回调函数名称
            _tempName = 'APP_RESULT_FUN_' + _id++;
            // 定义函数
            window[_tempName] = function(data){
                // 执行自定义回调
                callback(data);
            };
            // 传递函数名称到目标页面
            ex.callbackName = _tempName;
            
            // 显示菊花
            cw = plus.nativeUI.showWaiting();
            
            // 创建目标页面 
            ow = plus.webview.create(url, id, {
                render: "always"
            }, ex);
            // title更新时显示 页面
            ow.addEventListener('titleUpdate', function(){
                // 关闭菊花
                cw && (cw.close(),cw = null);
                // 显示页面
                ow.show('pop-in');
            });
            // 页面关闭时,注销window下此次事件
            ow.addEventListener('close', function(){
                  setTimeout(function(){
                      window[_tempName] = null;
                  });
            });
            
        };

生成特殊一个函数,并把函数名通过extras的方式传参到目标页面,
相应的,setResult方法也需要少许更改

    /**
     * 返回创建者页面数据
     * @param {Object} data 需要返回的数据
     * @return {Webview} w 当前webview
     */
    app.setResult = function(data) {
        // 获取当前webview
        var indexW = plus.webview.currentWebview();
        // js字符串
        var jsstr = "";
        // 如果存在自定义回调函数名
        if(indexW.callbackName){
            // 拼接js字符串
            jsstr = "window." + indexW.callbackName;
            jsstr = jsstr + "&&" + jsstr + "(" + JSON.stringify(data) + ")";
            // 执行
            indexW.opener().evalJS(jsstr);
        }
        // 返回当前页面
        return indexW;
    };

试试引用后在AB页面测试一下

            // A页面 按钮点击事件
            document.querySelector(".mui-btn-blue").addEventListener('tap', function(){
                // 打开B页面,选取一个结果
                app.onActivityResult('B.html', 'B', {}, function(data){
                    // 修改内容
                    document.querySelector("input").value = data.text;
                });
            });
            
            // B页面 选项点击事件
            mui('ul').on('tap', 'li', function() {
                // 获取当前选择的内容
                var text = this.innerText;
                // 通知上个页面 并关闭本页面
                app.setResult({
                    text: text
                }).close();
            });

卧槽666。

class Man{
    constructor(){
        this.name = 'newsning'
    }
    say(){
        console.log('天行健, 君子以自强不息. ')
    }
}
在Android上使用ZXING库(Zebra Crossing Library)实现二维码扫描通常涉及以下几个步骤: 1. 添加依赖:首先,在你的项目中引入ZXING库。如果你使用的是Gradle,可以在build.gradle文件中添加: ```groovy dependencies { implementation 'com.journeyapps:zxing-android-embedded:3.5.0' } ``` 2. 初始化Intent:创建一个Intent,启动ZXing库提供的Activity来扫描二维码。这通常是通过`startActivityForResult()`方法: ```java Uri cameraURI = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "temp.jpg")); IntentIntegrator integrator = new IntentIntegrator(this); integrator.setDesiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES); // 可选地设置只扫描特定类型的二维码 integrator.setPrompt("Scan a QR code"); // 扫描提示 intent = integrator.createChooserIntent(); startActivityForResult(intent, REQUEST_CODE_SCAN); ``` 3. onActivityResult()处理:当用户扫描成功后,会回调到这个方法,你可以从`data.getStringExtra("SCAN_RESULT")`获取扫描结果,并解析数据。 4. 显示扫描结果:如果扫描结果显示在webview中,你需要将结果赋值给WebView的HTML内容: ```java String webViewResult = data.getStringExtra("SCAN_RESULT"); webView.loadData("<html><body>Scanned QR Code: " + webViewResult + "</body></html>", "text/html", null); ``` 5. 错误处理:在用户取消扫描或者扫描失败时,也需要处理相应的逻辑,比如检查`resultCode`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值