H5判断当前是否引入 JSBridge

H5判断当前是否引入 JSBridge

判断场景
1. 如当前版本未接入jsbridge,无法通过jsbridge库中的方法判断是否注入了对象或者方法事件。
【婉转的解决方法】
1. 设置一个当前页面全局变量 flag=false;
2. 通过页面渲染完成后,直接调用 “获取app基本信息——getAppInfo” 该方法。如果当前app版本未接入jsbridge,则调用该方法无效,无法输出相关数据,即 flag = false。提示用户需升级新版本;
3. 如果当前版本已经接入jsbridge,则调用 “getAppInfo” 该方法后,正常输出数据, flag = true;后续只判断 调用API后APP返回101错误的处理。

Android

一、Android H5 页面示例

示例链接:http://cms.shenliangzhu.bevateachers.com/yichaowang_share/H5_buy_jsbridge/home_android.html

二、Android 代码示例
第一段代码【基础代码】
var u = navigator.userAgent,
    isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
function connectWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) {
        callback(WebViewJavascriptBridge)
    } else {
        if (!isAndroid) {
            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)
        } else {
            document.addEventListener('WebViewJavascriptBridgeReady', function(event) {
                callback(WebViewJavascriptBridge)
            }, false)
        }
    }
}

【备注:在android中,在生成第一段 基础代码后 必须再初始化一下,所有在第三段页面dom加载后进行了初始化代码操作】


第二段代码【APP&H5联动注册事件】
// 获取用户信息 测试
function getUserInfoFun() {
    addLog("测试 onload 中调用了该函数 获取用户信息数据")
    connectWebViewJavascriptBridge(function(bridge) {
        // 提交给app的数据
        var data = {
            "method": "getUserInfo",
            "param": {}
        }
        addLog('JS调用APP:' + JSON.stringify(data))
        bridge.callHandler('bevaAppHandler', data, function(response) {
            addLog('APP回调 返回数据======:' + JSON.stringify(response))
            // 如果可以调用该函数  则表示该页面注入了 jsbridge
            js_flag = true                      
            // checkJsbridgeFn(js_flag,JSON.stringify(response))
        })
    });
}
// 应用内支付
function inAppPurchaseFn(producttype,productid,orderdesc,price,originalprice) {
    var param = {
        "productType": producttype,
        "productId": productid,
        "orderDesc": orderdesc,
        "price":price,
        "originalPrice":originalprice
    }
    if(js_flag==false){
        $('.beva-mask').show()
        return
    }
    connectWebViewJavascriptBridge(function(bridge) {
        // 提交给app的数据
        var data = {
            "method": "inAppPurchase",
            "param": param
        }
        addLog('JS调用APP:' + JSON.stringify(data))

        bridge.callHandler('bevaAppHandler', data, function(response) {
            var p = JSON.parse(response)
            addLog("【response.resultCode===】" +   p.resultCode + "】】】】")
            addLog('APP回调 返回数据======:' + response)
            if(p.resultCode==101){
                addLog("【判断当前的方法是否存在】")
                $('.beva-mask').show()
                return
            }
        })
    });
}

【备注:在android中,app返回给H5的数据格式是 string ,需要进行转换成 json,才可以判断当前方法的存在与否】


第三段代码 【页面DOM初始化】
// 设置当前页面的全局变量
var js_flag = false;
$(function(){           
    // 此处将 初始化 放置在此处是为了让 jsbridge 在页面DOM渲染完成后 再进行初始化
    // 初始化jsbridge 以及注册事件
    connectWebViewJavascriptBridge(function(bridge) {
        bridge.init(function(data, responseCallback) {
            responseCallback(data)
        })
        bridge.registerHandler('bevaJSHandler', function(data, responseCallback) {
            responseCallback(data)
        })
    });
    // 测试查看 jsbridge 是否已经成功注入 直接调用
    // 理论上直接调用 getUserInfoFun() 函数来确定输出数据即可, 保险起见还是给了定时器延迟
    setTimeout(function() {
        getUserInfoFun()
    }, 500);
})

iOS

一、iOS H5页面示例

示例链接:http://cms.shenliangzhu.bevateachers.com/yichaowang_share/H5_buy_jsbridge/home_ios.html

二、iOS 代码示例
第一段代码【基础代码】
function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) {
        return callback(WebViewJavascriptBridge);
    }
    if (window.WVJBCallbacks) {
        return window.WVJBCallbacks.push(callback);
    }
    window.WVJBCallbacks = [callback];
    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)

    setupWebViewJavascriptBridge(function(bridge) {
        //注册一个方法(方法名是“bevaJSHandler”)
        bridge.registerHandler('bevaJSHandler', function(data, responseCallback) {
            addLog('注册 一个名为“bevaJSHandler”的方法,客户端进行调用')
            responseCallback(data)
        })
    })
}

【备注:在iOS中,无需像Android中一样对jsbridge进行初始化操作,所以只需要引入第一段代码即可,无需再在页面DOM渲染完成后进行初始化声明】


第二段代码【APP&H5联动注册事件】
// 获取用户信息 测试
function getUserInfoFun() {
    setupWebViewJavascriptBridge(function(bridge) {
        // 提交给app的数据
        var data = {
            "method": "getUserInfo",
            "param": {}
        }
        addLog('JS调用APP:' + JSON.stringify(data))
        bridge.callHandler('bevaAppHandler', data, function(response) {
            addLog('APP回调 返回数据======:' + JSON.stringify(response))
            js_flag = true  
        })
    });
}
// 应用内支付
function inAppPurchaseFn(id) {
    var param = {
        "iOS_productId": id
    }
    if(js_flag==false){
        $('.beva-mask').show()
        return
    }
    setupWebViewJavascriptBridge(function(bridge) {
        // 提交给app的数据
        var data = {
            "method": "inAppPurchase",
            "param": param
        }
        addLog('JS调用APP:' + JSON.stringify(data))
        bridge.callHandler('bevaAppHandler', data, function(response) {
            addLog('APP回调 返回数据======:' + JSON.stringify(response))
            addLog("【查看当前方法状态码】==="+ response.resultCode)
            if(response.resultCode==101){
                $('.beva-mask').show()
                return
            }
        })
    });
}

【备注:第二段代码中,app返回给H5的数据格式是 json,不用和 Android 中一样进行格式转化,直接使用即可】


第三段代码【页面DOM初始化】
var js_flag = false;
$(function() {
    // 测试查看 jsbridge 是否已经成功注入 直接调用
    // 理论上直接调用 getUserInfoFun() 函数来确定输出数据即可, 保险起见还是给了定时器延迟
    setTimeout(function() {
        getUserInfoFun()
    }, 500);
    touchMoveNo()
})