美文网首页ionic3+我的ionicionic+cordova
Cordova插件使用——Themeablebrowser数据花

Cordova插件使用——Themeablebrowser数据花

作者: IT晴天 | 来源:发表于2018-01-27 22:21 被阅读564次

    Themeablebrowser是一个外部浏览器插件,它fork自inappbrowser,相比于后者,此插件的目的是提供一个可以与你的应用程序的主题相匹配的in-app-browser,以便给你的应用保持一致的外观和感觉。所以,除了一些主题化的配置外,核心部分使用参考inappbrowser文档。

    inappbrowser的方法有以下几个,通过它们实现js和插件的交互:

    • addEventListener
    • removeEventListener
    • close
    • show
    • hide
    • executeScript
    • insertCSS

    而其中,又主要使用addEventListenerexecuteScript

    -- addEventListener

    使用方式如下:

    ref.addEventListener(eventname, callback);
    

    其中eventname,即事件名只有以下4个:

    • loadstart: 当InAppBrowser开始加载一个URL时抛出事件.
    • loadstop: 当InAppBrowser结束加载一个URL时抛出事件.
    • loaderror: 当InAppBrowser加载一个URL出现错误时抛出事件.
    • exit: 当InAppBrowser窗口关闭时抛出事件.

    -- executeScript

    使用方式如下:

    ref.executeScript(details, callback);
    

    其中details,是要运行的js脚本,可以指定文件或代码:

    • file: 要注入的js脚本的URL.
    • code: 要注入的js脚本文本.

    从注入脚本和可用事件提供的信息来看,数据传输是单向的,与http协议无状态概念一致,也就是说一般使用仅是应用主动向浏览器插件发送数据,然后接收回调信息,然而,若想浏览器插件主动传递数据给应用,也不是不可以的!

    准备工作(1)——准备供浏览器插件访问的网页

    新建并发布一个网页,供浏览器插件访问。这里我简单用node搭建一个网页(由上往下分别是创建目录、跳过询问来配置package.json、安装express):

    mkdir testWeb && cd testWeb
    npm init -y
    npm i express --save
    

    新建index.js文件,并填入以下内容:

    const express = require('express')
    const path = require('path')
    const app = express()
    
    app.use(express.static(__dirname))
    app.listen(8089, () => {
      console.log(`App listening at port 8089`)
    })
    

    这样就部署了个静态网页服务器,我们再创建一个html页面和一个js文件:
    index.html:

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
      <title>父子组件参数传递测试</title>
    </head>
    <body>
      <h1>父子组件参数传递测试</h1>
      <button id="btnGet">接收参数</button>
      <button id="btnReturnByJump">基于跳转返回数据</button>
      <button id="btnReturnByDetect">基于监测返回数据</button>
      <script src="test.js"></script>
    </body>
    </html>
    

    test.js:

    var fromAppData = '';
    var jumpData = '';   //跳转的返回数据
    var detectData = '';    //检测的返回数据
    var btnGet = document.getElementById("btnGet");
    btnGet.onclick = function(){
        alert(JSON.stringify(fromAppData));
    }
    
    function sayHello(data){
        detectData = '';
        fromAppData = data;
        alert(data.text);
        return 'world';        //区分data.text,这里返回任意值
    }
    
    var btnReturnByJump = document.getElementById("btnReturnByJump");
    btnReturnByJump.onclick = function(){
        jumpData = 'jump:' + new Date().getTime();
        window.open('close');
    }
    /**
     * 获取跳转返回的数据
     */
    function getJumpData(){
        return jumpData;
    }
    
    var btnReturnByDetect = document.getElementById("btnReturnByDetect");
    btnReturnByDetect.onclick = function(){
        detectData = 'detect:' + new Date().getTime();
        alert(detectData);
    }
    
    /**
     * 获取检测的数据
     */
    function getDetectData(){
        return detectData;
    }
    

    执行命令启动:

    node index.js
    

    在浏览器访问一下是否能正常运行:http://localhost:8089,实际真机测试时换成IP访问:http://192.168.2.130:8089

    准备工作(2)——安装插件

    hybird应用执行命令安装插件:

    cordova plugin add cordova-plugin-themeablebrowser
    

    测试APP主动向插件发送数据,并获取返回。

    在应用中添加调用插件接口:

     var ref = cordova.ThemeableBrowser.open('http://192.168.2.130:8089/index.html', '_blank', {
          closeButton: {
            image: 'close',
            imagePressed: 'close_pressed',
            align: 'left',
            event: 'closePressed'
          },  
          customButtons: [
            {
              image: 'share',
              imagePressed: 'share_pressed',
              align: 'right',
              event: 'sharePressed'
            }]
     })
    .addEventListener('sharePressed', function (event) {
          ref.executeScript({ code: "getJumpData()" }, (params) => {
             console.log(JSON.stringify(params));
          });
    });
    
     ref.addEventListener('loadstop', function (params) {
          //调用浏览器内部页面的js方法
          ref.executeScript({ code: "sayHello({text: 'hello'})" }, (params) => {
              console.log(params);
          });
    });
    

    在loadstop响应事件后注入js调用内部网页的方法sayHello,这样,在URL加载完成后就会执行该方法,为了测试json数据是否正常传递,浏览器内部页面的方法打印data.text,并返回“world”,结果如下图正确输出:

    image.png

    同时,点击浏览器页面的【接收参数】按钮,也是能正确打印出传递进来的fromAppData

    测试插件主动向APP传送数据。

    方法还是有不少的,现举三种方法抛砖引玉一下:

    1. 页面跳转法
    在APP里面添加下面事件监听的代码:

     ref.addEventListener('loadstart', (event) => {
          if (event.url.match("close")) {
            ref.executeScript({ code: "getJumpData();" }, (params) => {
              console.log(JSON.stringify(params));
              ref.close();
            });
          }
        });
    

    观察下,在浏览器页面的test.js里面有以下内容:

    var btnReturnByJump = document.getElementById("btnReturnByJump");
    btnReturnByJump.onclick = function(){
        jumpData = 'jump:' + new Date().getTime();
        window.open('close');
    }
    

    上面的内容结合起来的意思是:【基于跳转返回数据】按钮点击后保存一个变量jumpData,然后调用window.open('close')实现跳转,此时会被loadstart事件监听到,再注入js脚本获取jumpData数据,在控制台是看到有如下正确输出的:

    image.png

    2. 轮询监测法
    在当年没有用推送的老时代,轮询是一种常见但耗费性能的方法,在这里可以用一下。
    在APP里面修改下面事件监听的代码:

     ref.addEventListener('loadstop', (event) => {
          ref.executeScript({ code: "sayHello({text: 'hello'})" }, (params) => {
            console.log(params);
          });
          //启动定时器
          var loop = setInterval(() => {
            ref.executeScript({ code: "getDetectData()" }, (params) => {
              var detectData = params[0];
              if (detectData) {
                console.log(detectData);
                //销毁定时器
                clearInterval(loop);
                ref.close();
              }
            }, 500);
          });
        });
    

    再次观察下,在浏览器页面的test.js里面有以下内容:

    var btnReturnByDetect = document.getElementById("btnReturnByDetect");
    btnReturnByDetect.onclick = function(){
        detectData = 'detect:' + new Date().getTime();
        alert(detectData);
    }
    

    上面的内容结合起来的意思是:【基于监测返回数据】按钮点击后设置一个变量detectData,此时会被APP里面的轮询监测到detectData不为空时,就打印数据,并停止轮询,在浏览器也是能正常输出的。

    3. 浏览器插件自定义原生按钮法
    APP里面留意到下面代码:

    .addEventListener('sharePressed', function (event) {
          ref.executeScript({ code: "getJumpData()" }, (params) => {
             console.log(JSON.stringify(params));
          });
    });
    

    在浏览器页面操作保存临时数据后,利用自定义原生按钮事件,把数据传递出来。

    仅给出大致思路抛个砖,有兴趣的自行深挖吧。

    相关文章

      网友评论

      • 北海里淹不死的鱼:你好,为什么我第一次执行绑定的event事件的时候没有起到作用呢?

        browser.addEventListener('backPressed',(e)=>{
        browser.close();
        })

        第二次点击的时候,插件页面才关闭,请问作者有遇到过吗?感谢
      • 七月雨纷纷:又学会一个骚操作
      • 候鸟_ywh:原来是可以这样的啊,之前好多人问这个怎么操作,老晴厉害

      本文标题:Cordova插件使用——Themeablebrowser数据花

      本文链接:https://www.haomeiwen.com/subject/swpepxtx.html