上代码
1.创建 src/utils/bridge.js文件,用于封装 WebViewJavascriptBridge
2.bridge.js 文件下的代码如下:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback];
let WVJBIframe = document.createElement('iframe')
WVJBIframe.style.display = 'none'
WVJBIframe.src = 'https://__bridge_loaded__'
document.documentElement.appendChild(WVJBIframe);
setTimeout(() => {
document.documentElement.removeChild(WVJBIframe)
}, 0)
}
export default {
callhandler(name, data, callback) {
// 调用客户端的方法
setupWebViewJavascriptBridge(function (bridge) {
bridge.callHandler(name, data, callback)
})
},
registerhandler(name, callback) {
// 客户端需要调用的js函数
setupWebViewJavascriptBridge(function (bridge) {
bridge.registerHandler(name, function (data, responseCallback) {
callback(data, responseCallback)
})
})
},
}
3.在main.js中引入该文件:
import bridge from './util/bridge' //引用WebViewJavascriptBridge
Vue.prototype.$bridge=bridge;
在需要调用客户端方法的组件中调用(事先需要与客户端同事约定好方法名)
let params={} //需要传给客户端的参数
this.$bridge.callhandler("事先与客户端同事约定好的方法名", params, (data) => {
// alert(data) 返回的数据
// 处理返回数据
});
当客户端需要调用js函数的时候 (在对应的组件中注册事先约定的函数即可)
this.$bridge.registerhandler(
"事先与客户端同事约定好的方法名",
(data, responseCallback) => {
// alert(data) 返回的数据
// responseCallback(params); 如果有需要传给客户端同事的数据写在 params 里面
});
到这里写完了 ,检查了一遍代码觉得没毛病 开始测试 在ios上一切正常。然而在Android上调用 this.$bridge.callhandler 在vue中回调却接收不到返回值,Android的同事也拿不到this.$bridge.registerhandler中 提前约定注册好的方法名。疯狂Google之后新增了以下代码:
let u = navigator.userAgent;
function setupWebViewJavascriptBridge(callback) {
if (!/(iPhone|iPad|iPod|iOS)/i.test(u)) { //Android使用
if (window.WebViewJavascriptBridge) {
callback(window.WebViewJavascriptBridge);
} else {
document.addEventListener(
"WebViewJavascriptBridgeReady",
function() {
callback(window.WebViewJavascriptBridge);
},
false
);
}
}else{ //IOS使用
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge)
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback];
let WVJBIframe = document.createElement('iframe')
WVJBIframe.style.display = 'none'
WVJBIframe.src = 'https://__bridge_loaded__'
document.documentElement.appendChild(WVJBIframe);
setTimeout(() => {
document.documentElement.removeChild(WVJBIframe)
}, 0)
}
}
//注册回调函数,安卓
setupWebViewJavascriptBridge((bridge) => {
if (!/(iPhone|iPad|iPod|iOS)/i.test(u)) {
//android 有init初始化方法,必须调用 不调用后续注册的事件将无效 而IOS却没有init方法 调用会报错
bridge.init((message, responseCallback) => {
var data = { "Javascript Responds": "Wee!" };
console.log(message);
responseCallback(data);
});
}
});
export default {
callhandler(name, data, callback) {
// 调用客户端的方法
setupWebViewJavascriptBridge(function (bridge) {
bridge.callHandler(name, data, callback)
})
},
registerhandler(name, callback) {
// 客户端需要调用的js函数
setupWebViewJavascriptBridge(function (bridge) {
bridge.registerHandler(name, function (data, responseCallback) {
callback(data, responseCallback)
})
})
},
}
改完以后再次测试 ,Android和ios测试通过。