在實際專案之中,經常會遇到app之中嵌入網頁的情況(Hybrid),就需要web網頁與原生app之間互動,比如獲取當前使用者資訊等。一種簡單的方式就是通過url引數來搞定,但是這種方式異常死板,所以有了jsbridge。
本文章旨在記錄WebViewJavascriptBridge的實現,如有錯誤,還請指正!如有需要了解jsbridge原理,請google。
需求:
/**
* 函式描述:js呼叫webview事件
*
* jsBridge.callHandler(method, data, callBack(response));
* @param method {string} 方法名
* @param data {Object} 引數
* @return {Object} 回撥
*/
/**
* 函式描述:webView呼叫JS事件
*
* jsBridge.registerHandler(method, callBack(response));
* @param method {string} 方法名
* @return {Object} 回撥
*/
const JsBridge = {
init: function (callback) {
const u = navigator.userAgent;
const isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/); //判斷手機系統
if (!isiOS) { //ios
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
// 註冊事件,WebViewJavascriptBridge載入完成時呼叫
document.addEventListener(
`WebViewJavascriptBridgeReady`,
function () {
callback(WebViewJavascriptBridge)
},
false
);
}
} else { //Android
// 如果有WebViewJavascriptBridge,則直接返回callback
if (window.WebViewJavascriptBridge) {
return callback(WebViewJavascriptBridge);
}
// 如果有WVJBCallbacks,則向WVJBCallbacks中注入事件
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback);
}
// 否則建立WVJBCallbacks
window.WVJBCallbacks = [callback];
const WVJBIframe = document.createElement(`iframe`);
WVJBIframe.style.display = `none`;
WVJBIframe.src = `wvjbscheme://__BRIDGE_LOADED__`;
document.documentElement.appendChild(WVJBIframe);
setTimeout(function () {
document.documentElement.removeChild(WVJBIframe)
}, 0)
}
},
first: function () {
const u = navigator.userAgent;
const isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/);
if (!isiOS) {
const _this = this;
_this.init(function (bridge) {
bridge.init(function (message, responseCallback) {
responseCallback(data);
})
})
}
},
registerHandler: function (name, fun) {
const _this = this;
_this.init(function (bridge) {
bridge.registerHandler(name, fun);
})
},
callHandler: function (name, data, fun) {
const _this = this;
_this.init(function (bridge) {
bridge.callHandler(name, data, fun);
})
}
}
// 初始化
JsBridge.first();