业务需求:
前期在微信H5端与iOS和Android进行数据交互,借助的是封装的 WebViewJavascriptBridge 函数与iOS进行数据交互,然而与Android的数据交互还是一依据将交互的事件函数挂载到window上,以便于Android端app获取事件函数。虽然这种做法可以实现最终的效果,因为H5活动页面在iOS端app、Android端app以及微信端H5三端使用,与此同时还要依据不同参数或者不同ua信息处理不同的事件,相对来说代码逻辑比较复杂、冗余,容易出错,为此就寻找一个可以多端公用的方法。 本次封装的JS与APP进行数据交互的方法解决了iOS、Android、WeChat三端共用的问题,代码逻辑结构清晰明了、便于后续逻辑的调整和优化。
首先判断设备信息:
var u = navigator.userAgent;
// Android 终端
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
// iOS 终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
var isWeChat = u.match(/MicroMessenger/ig) == "micromessenger";
// 或者
let ua = navigator.userAgent;
// Android 端
let isAndroid = ua.indexOf("Android") > -1 || ua.indexOf("Linux") > -1;
// iOS 终端
let isiOS = /iPhone|mac|iPod|iPad/i.test(ua);
//WeChat 终端
let isWeChat = !!window.__wxjs_is_wkwebview;
注:通过navigator.userAgent获取设备信息,在依据不同设备的不同参数来区分当前设备所处的环境是Android、iOS还是WeChat。
封装Android和iOS端共用方法:
function connectWebViewJavascriptBridge(callback) {
if (isAndroid) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady',
function() {
callback(WebViewJavascriptBridge)
},
false
);
}
return;
}
if (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)
}
}
// 调用注册方法
connectWebViewJavascriptBridge(function(bridge) {
if (isAndroid) {
bridge.init(function(message, responseCallback) {
responseCallback(data);
});
}
});
事件交互:
// 调用Android和iOS端方法,并接收返回数据回调js方法
window.WebViewJavascriptBridge.callHandler('jsToAppFn', {
orderInfo: data
}, function(res) {
window.console.log(res)
});
// 提供js方法供Android和iOS端调用
window.WebViewJavascriptBridge.registerHandler('appToJsFn', function(data, responseCallback) {
// data 是 APP 传递过来的数据.
// data数据两端协商好,若使用JSON字符串,js端需要转换JSON对象
// responseCallback 是 JS 调用完毕之后传递给 APP 的数据
responseCallback({
key: 'value'
});
});