一、背景以及实现介绍
为了使H5能够调用原生提供的方法,在H5页面的window对象上注入一个JavaScript可以访问到的对象WebBridge。
bridge.js已经做好了封装。
1、H5调用原生方法:
hxWebBridge.handlerJSMessage(arg1, arg2)
参数arg1:
json格式的字符串:{"Method":”callScan", "Data”:{}}
arg2:
表示回调方法的名称,假设是:CB_1521683233444_3
2、原生回调H5:
window.CB_1521683233444_3(null, json对象)
json对象结构约定如下:
{"Method”:”CB_1521683233444_3", "result”:{“url”:”"}}
二、使用方式举例
引入bridge.js文件,调用方式如下:
window.webBridge.callHandler('callScan', null, function (errMsg, res) {
if (errMsg !== null && errMsg !== 'undefined' && errMsg !== 'null') {
return reject('service no result back');
} else {
return resolve(res);
}
});
将brige.js导入main.js中
附bridge.js
(function (win) {
var ua = navigator.userAgent;
function getQueryString(name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
var r = window.location.search.substr(1).match(reg);
if (r !== null) return unescape(r[2]);
return null;
}
function isAndroid() {
return ua.indexOf('Android') > 0;
}
function isIOS() {
return isIosWKWebView() || /(iPhone|iPad|iPod)/i.test(ua);
}
function isIosWKWebView() {
return (
!!win.webkit &&
!!win.webkit.messageHandlers &&
!!win.webkit.messageHandlers.hxWebBridge
)
}
// invoke callbaks
const callbacks = {}
let callbackIndex = 0
var messageHandlers = {};
var mobile = {
/**
*通过bridge调用app端的方法(异步)
* @param method
* @param params
* @param callback function(err, result)函数
*/
callHandler: function (method, params, callback) {
if (!isIosWKWebView() && (!win.hxWebBridge || !win.hxWebBridge.handlerJSMessage)) {
return false;
}
var req = {
'Method': method,
'Data': params
};
if (isIOS()) {
if (isIosWKWebView()) {
const callbackId = ++callbackIndex
callbacks[callbackId] = callback
win.webkit.messageHandlers.hxWebBridge.postMessage({
Method: method,
Data: params,
callbackId: callbackId
})
} else {
win.hxWebBridge.handlerJSMessage(req, function (err, result) {
var resultObj = null;
var errorMsg = null;
if (typeof (result) !== 'undefined' && result !== 'null' && result !== null) {
resultObj = JSON.parse(result);
if (resultObj) {
resultObj = resultObj['result'];
}
}
if (err !== 'null' && typeof (err) !== 'undefined' && err !== null) {
errorMsg = err;
}
callback(err, resultObj);
});
}
} else if (isAndroid()) {
// 生成回调函数方法名称
var cbName = 'CB_' + Date.now() + '_' + Math.ceil(Math.random() * 10);
// 挂载一个临时函数到window变量上,方便app回调
win[cbName] = function (err, result) {
var resultObj;
if (typeof (result) !== 'undefined' && result !== null) {
resultObj = JSON.parse(result)['result'];
}
callback(err, resultObj);
// 回调成功之后删除挂载到window上的临时函数
delete win[cbName];
};
win.hxWebBridge.handlerJSMessage(JSON.stringify(req), cbName);
}
},
/**
*通过bridge调用app端的方法(同步)
* @param method
* @param params
*/
callHandlerSync: function (method, params) {
if (!isIosWKWebView() && (!win.hxWebBridge || !win.hxWebBridge.handlerJSMessage)) {
return false;
}
var req = {
'Method': method,
'Data': params
};
var returnVal = {};
if (isIOS()) {
if (isIosWKWebView()) {
returnVal = prompt("handlerJSMessage", JSON.stringify(req));
if (returnVal && returnVal !== 'null' && typeof (returnVal) === "string") {
returnVal = JSON.parse(returnVal);
}
} else {
returnVal = win.hxWebBridge.handlerJSMessageSync(req);
if (returnVal && returnVal !== 'null' && typeof (returnVal) === "string") {
returnVal = JSON.parse(returnVal);
}
}
} else if (isAndroid()) {
returnVal = prompt("handlerJSMessage", JSON.stringify(req));
if (returnVal && returnVal !== 'null' && typeof (returnVal) === "string") {
returnVal = JSON.parse(returnVal);
}
}
return returnVal;
},
// iOS WKWebView时,当H5调用原生方法时,不能传匿名函数到原生,所有原生实现功能后需要调用此方法回调
handlerJSMessageCallbackHandler: function (callbackId, params) {
const callback = callbacks[callbackId];
if (typeof callback === 'function') {
var err = params['errMsg'];
var result = params['result'];
var resultObj = null;
if (typeof (result) !== 'undefined' && result !== 'null' && result !== null) {
resultObj = JSON.parse(result);
}
callback(err, resultObj);
}
},
/**
*通过bridge来handler app端调用的方法
* @param method
* @param handler function(params, function(err, result))函数
*/
registerHandler: function (method, handler) {
messageHandlers.method = handler;
},
/**
*私有方法,只会在native端调用
*/
handlerNativeMessage: function (params) {
var method = params['Method'];
var data = params['Data'];
var handler = messageHandlers.method;
var responseCallback = function (err, result) {
var response = {};
response['Method'] = method;
response['err'] = err;
response['result'] = result;
if (isIosWKWebView()) {
prompt("jsResponseCallback", JSON.stringify(response));
} else {
window.hxWebBridge.jsResponseCallback(JSON.stringify(response));
}
};
if (handler != null) {
handler(data, responseCallback);
} else {
responseCallback('JS Method not found', null);
}
}
};
// 将mobile对象挂载到window全局
win.webBridge = mobile;
})(window);