Themeablebrowser是一个外部浏览器插件,它fork自inappbrowser,相比于后者,此插件的目的是提供一个可以与你的应用程序的主题相匹配的in-app-browser,以便给你的应用保持一致的外观和感觉。所以,除了一些主题化的配置外,核心部分使用参考inappbrowser文档。
inappbrowser的方法有以下几个,通过它们实现js和插件的交互:
而其中,又主要使用addEventListener和executeScript。
使用方式如下:
ref.addEventListener(eventname, callback);
其中eventname
,即事件名只有以下4个:
使用方式如下:
ref.executeScript(details, callback);
其中details
,是要运行的js脚本,可以指定文件或代码:
从注入脚本和可用事件提供的信息来看,数据传输是单向的,与http协议无状态概念一致,也就是说一般使用仅是应用主动向浏览器插件发送数据,然后接收回调信息,然而,若想浏览器插件主动传递数据给应用,也不是不可以的!
新建并发布一个网页,供浏览器插件访问。这里我简单用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
hybird应用执行命令安装插件:
cordova plugin add cordova-plugin-themeablebrowser
在应用中添加调用插件接口:
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
方法还是有不少的,现举三种方法抛砖引玉一下:
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)); }); });
在浏览器页面操作保存临时数据后,利用自定义原生按钮事件,把数据传递出来。
仅给出大致思路抛个砖,有兴趣的自行深挖吧。
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句