在實際項目之中,常常會遇到app之中嵌入網頁的狀況(Hybrid),就須要web網頁與原生app之間交互,好比獲取當前用戶信息等。一種簡單的方式就是經過url參數來搞定,可是這種方式異常死板,因此有了jsbridge。
本文章旨在記錄WebViewJavascriptBridge的實現,若有錯誤,還請指正!若有須要瞭解jsbridge原理,請google。ios
需求:web
/** * 函數描述: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();