构建JsBridge
,基于客户端webview
提供对应交互框架,目前仅提供h5端的使用。
/**
* JsBridge 提供和native通信的桥接功能
*/
const JsBridge = function () {
this.bridge = null // 桥接对象
this.platform = getPlatform() // 当前客户端平台
this.init()
}
/**
* 获取客户端平台类型
*/
function getPlatform() {
var userAgent = navigator.userAgent.toLowerCase()
var name = 'Unknown'
if (userAgent.indexOf('win') > -1) {
name = 'Windows'
} else if (userAgent.indexOf('iphone') > -1) {
name = 'Ios'
} else if (userAgent.indexOf('mac') > -1) {
name = 'Mac'
} else if (userAgent.indexOf('x11') > -1 || userAgent.indexOf('unix') > -1 || userAgent.indexOf('sunname') > -1 || userAgent.indexOf('bsd') > -1) {
name = 'Unix'
} else if (userAgent.indexOf('linux') > -1) {
if (userAgent.indexOf('android') > -1) {
name = 'Android'
} else {
name = 'Linux'
}
} else {
name = 'Unknown'
}
return name
}
/**
* log 将日志输出到dom上
* @param {string} message
* @param {*} data
*/
function log(message, data) {
var log = document.getElementById('log')
if (log) {
var el = document.createElement('div')
el.className = 'logLine'
el.innerHTML = message + ':====== ' + JSON.stringify(data) + ' ======'
if (log.children.length) { log.insertBefore(el, log.children[0]) } else { log.appendChild(el) }
} else {
console.log(message + ':====== ' + JSON.stringify(data) + ' ======')
}
}
var fn = JsBridge.fn = JsBridge.prototype
/**
* 初始化bridge
* @param {Function} done
*/
fn.init = function (done) {
if (this.platform === 'Ios') {
this.setupIosWebViewJavascriptBridge(bridge => {
if (bridge) {
this.bridge = bridge
this.registerHandler()
log('init msg', 'bridge实例挂载成功')
// bridge初始化有延迟
setTimeout(() => done && done(bridge), 500)
} else log('init msg', 'bridge实例挂载失败')
})
}
else if (this.platform === 'Android') {
this.setupAndroidWebViewJavascriptBridge(bridge => {
if (bridge) {
this.bridge = bridge
log('init msg', 'bridge实例挂载成功')
// bridge初始化有延迟
setTimeout(() => done && done(bridge), 500)
} else log('init msg', 'bridge实例挂载失败')
})
}
}
/**
* JSBRIDGEH5端注册事件
*/
fn.registerHandler = function () {
log('registerHandler msg', 'JSBRIDGEH5端注册事件')
this.bridge.registerHandler('testJavascriptHandler', function (data, responseCallBack) {
log('registerHandler msg', data)
responseCallBack && responseCallBack(data)
})
}
/**
* Android 接入方式
*/
fn.setupAndroidWebViewJavascriptBridge = function (callback) {
var bridge = window.WebViewJavascriptBridge || window.WKWebViewJavascriptBridge;
if (bridge) { return callback(bridge); }
var callbacks = window.WVJBCallbacks || window.WKWVJBCallbacks;
if (callbacks) { return callbacks.push(callback); }
window.WVJBCallbacks = window.WKWVJBCallbacks = [callback];
if (window.WKWebViewJavascriptBridge) {
window.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null);
} else {
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);
}
}
/**
* Ios jsBridge 接入方式
*/
fn.setupIosWebViewJavascriptBridge = function (callback) {
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback]
var WVJBIframe = document.createElement('iframe')
WVJBIframe.style.display = 'none'
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'
document.documentElement.appendChild(WVJBIframe)
setTimeout(function () { document.documentElement.removeChild(WVJBIframe) }, 0)
}
/**
* 调用bridge公用方法
* @param {string} eventName 事件名
* @param {object} data 参数
* @param {Function} done 回调
*/
fn.callHandler = function (eventName, data = {}, done) {
try {
const callFn = (bridge) => {
bridge.callHandler(eventName, data, function (responseData) {
log(eventName, responseData)
done && done(responseData)
})
}
if (!this.bridge) {
log(eventName, 'JsBridge未初始化')
this.init(callFn)
return
}
callFn(this.bridge)
} catch (error) { log(eventName, error) }
}
export default JsBridge
网友评论