原生APP跳转到H5页面时,往往需要携带一些用户信息,之前做法是在跳转的地址中拼接H5页面需要的参数,现在通过window.WebViewJavascriptBridge悄悄的进行数据交互。
下面从H5的角度记录交互思路:
1:安卓环境和ios环境稍微有点不同,需要根据navigator.userAgent判断一下当前环境
2:仍然是APP环境不同,安卓需要进行兼容性判断,如果不存在window.WebViewJavascriptBridge变量,需要手动添加Dom的WebViewJavascriptBridgeReady事件监听;
ios同样需要判断是否存在window.WebViewJavascriptBridge变量,如果不存在继续判断window.WVJBCallbacks变量,如果仍然不存在,则手动赋值为H5回调,然后document.createElement('iframe')插入document中,随即移除。
3:以上处理完成后,通过WebViewJavascriptBridge变量来注册【事件】以便APP能监听到并执行相应操作
4:3中需要对安卓系统进行init处理,如果是安卓系统,注册事件之前需要先调用WebViewJavascriptBridge.init()
方法(注意: 一个页面整个生命周期过程中,只能进行一次init()否则会报错,我的做法是通过一个全局变量来判断是否初始化过)
//针对安卓和ios系统,对window.WebViewJavascriptBridge进行兼容性处理
function setupWebViewJavascriptBridge(callback) {
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isAndroid) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
//添加dom事件
document.addEventListener(
'WebViewJavascriptBridgeReady',
function () {
callback(WebViewJavascriptBridge)
},
false
);
}
}
if (isiOS) {
console.log('isiOS')
if (window.WebViewJavascriptBridge) {
return callback(WebViewJavascriptBridge);
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback);
}
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function () {
document.documentElement.removeChild(WVJBIframe)
}, 0)
}
}
//封装方法,key:跟原生定义好的要捕获的名称, callback:原生捕获后执行的回调,此处可以写H5的后续执行方法,params:对象,要传给原生的参数
var setupWebViewBridge = function (key, callback, params) {
setupWebViewJavascriptBridge(function (bridge) {
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
//自己定义的全局变量,用来判断当前页面中安卓系统是否进行过一次初始化,页面卸载时取消赋值
if (!window.hadCalledWindow_WebViewJavascriptBridge ) {
if (isAndroid) {
window.hadCalledWindow_WebViewJavascriptBridge = true
bridge.init(function (message, responseCallback) {
console.log('JS got a message', message);
var data = {
'Javascript Responds': '测试中文!'
};
if (responseCallback) {
console.log('JS responding with', data);
responseCallback(data);
}
});
}
}
bridge.callHandler(
key,
//安卓系统必须传一个参数,否则捕获不到,因此,默认传入一个_x_变量
JSON.stringify({
...params,
_x_: 1,
}),
callback
);
})
}
原生APP里,注册要捕获的方法:
bridge.registerHandler('jsbridge_showMessage', function (data, responseCallback) {
showResponse(data);
});
来源:oschina
链接:https://my.oschina.net/u/560237/blog/3185010