1. <legend id="z1ta0"></legend>

          <label id="z1ta0"></label>

          <label id="z1ta0"></label>

            <big id="z1ta0"></big>

            Cordova插件使用——Themeablebrowser數據花式交互

            小編:管理員 281閱讀 2022.09.13

            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));
                  });
            });
            復制

            在瀏覽器頁面操作保存臨時數據后,利用自定義原生按鈕事件,把數據傳遞出來。

            僅給出大致思路拋個磚,有興趣的自行深挖吧。

            關聯標簽: