# THTML5 **Repository Path**: huqs/THTML5 ## Basic Information - **Project Name**: THTML5 - **Description**: THTML实现红包雨 - **Primary Language**: Objective-C - **License**: Not specified - **Default Branch**: huqs - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 3 - **Created**: 2016-01-20 - **Last Updated**: 2022-05-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 原生提供H5调用的函数 |序号| 方法名 | 说明 | Android |AppleIos| 备注 |:----:| :------- | :------ | :----: |:----:|:----: | |1| setTitle | 修改原生的标题 | 支持 | 支持 | | |2| navigation | 打开原生界面,保留原来界面 | 支持 | 支持 | | |3| redirect | 打开原生界面,不保留原来界面 | 支持 | 支持 | | |4| reLaunch | 打开原生界面,关闭其他所有的界面 | 支持 | 支持 | | |5| navigateBack | 关闭原生界面 | 支持 | 支持 | | |6| navigateBackByTag | 通过tag关闭原生界面,并跳转到tag指定的界面 | 支持 | 支持 | | |7| setResult | 设置要返回的上一个界面的数据 | 支持 | 支持 | | |8| addBackListener| 监听原生的返回键事件 | 支持 | 支持 |H5只要监听返回键,原生不在处理返回键的事件| |9| getUserInfo|获取用户信息 | 支持 | 支持 | | |10| addMenu|动态添加标题栏menu | 支持 | 支持 | 在原来的基础上添加 | |11| removeMenu|动态移除标题栏指定的menu | 支持 | 支持 | 通过标题(text)匹配| |12| removeAllMenu|动态移除所有的标题栏menu | 支持 | 支持 | | |13| chooseImages|从本地相册选择图片或使用相机拍照 | 支持 | 支持 | | |14| imageToBase64|把本地图片转Base64 | 支持 | 支持 | | |15| uploadFile|将本地资源上传到服务器 | 支持 | 支持 | | |15| scanCode|调起客户端扫码界面进行扫码 | 支持 | 支持 | | ### H5提供的回调函数 |序号| 方法名 | 说明 | Android | AppleIos | 备注 |:----:| :------- | :------ | :----: | :----: |:----: | |1| onNativeBridgeReady | 原生Native和H5通信桥梁建立完成时回调 | 支持 | 支持 | | |2| onNativeLoad | 原生界面初始化完成,相当于windows.onLoad但不等价,在windows.onLoad之后回调| 支持 | 支持 |只有首次打开会回调,页面刷新不会回调| |3| onNativeResult | 接收上一个界面关闭时传递过来的参数 | 支持 | 支持 | | |4| onNativeMenuItemSelected | 点击原生的Menu时回调 | 支持 | 支持 | | |5| onNativeBackListener| 点击返回键时回调 | 支持 | 支持 |只有监听返回键后才会回调| |6| onNativeDestroy| 原生界面关闭时回调 | 支持 | 支持 | | ### 内置Menu图标 |序号|名称|效果|Android|AppleIos |:----:| :----:| :----:| :----: | :----: |1|add|-|支持|支持| |2|search|-|支持|支持| |3|more|-|支持|支持| ### 如何使用 在H5中监听各个事件的回调: ```JavaScript // 原生Native和H5通信桥梁建立完成时回调 window.onNativeBridgeReady = function (jsBridge) { console.log("-------->原生Native和H5通信桥梁建立完成"); }; //原生界面初始化完成时回调,相当于windows.onLoad但不等价 window.onNativeLoad = function (params) { console.log("-------->收到参数:" + params); }; // 接收上一个界面返回时传递过来的参数 window.onNativeResult = function (params) { alert('收到上一个界面传递过来的参数:' + params); }; // 点击原生的Menu时回调 window.onNativeMenuItemSelected = function (params) { var menu = JSON.parse(params); alert('你点击了:' + menu.text); }; // 点击原生的返回键时回调 window.onNativeBackListener = function (text) { if (confirm("你确定要退出吗?")) { jsBridge.call("navigateBack"); } else { alert("点击了取消"); } } // 原生界面销毁,资源释放 window.onNativeDestroy = function (){ console.log("------------>onNativeDestroy页面销毁") } ``` #### 注意 * 1 所有的原生提供的回到函数都是onNative开头的。 * 2 只有在onNativeBridgeReady回调完成后才可以调用原生的方法,否则调用无效,该函数回调后自动在window中注入一个jsBridge对象可以通过它调用原生的方法。 * 3 所有的跨平台调用数据传递都使用Json,这样有效解决各个平台数据类型不同的问题。 * 4 调用原生所有的函数都是通过jsBridge.call(functionName,data,callback)的方式调用,functionName为原生提供的方法名,data是String类型数据,data最终会传递给原生, callback是JavaScript中的 function(函数)用于接收原生调用成功的反馈。 * 5 在H5中写JavaScript代码的时候声明变量时用要var 关键字,不能使用let关键字,因为在Android 5.0以前不支持这种写法。 * 6 在onNativeDestroy不能显示弹窗,因为页面已经销毁,在该函数内清楚数据缓存,或者缓存数据。 ### H5调原生各个方法演示 #### 1 H5设置原生的标题 "setTitle" ```JavaScript window.jsBridge.call("setTitle", 'APP混合开发'); ``` #### 2 打开原生界面,保留原来界面"navigation" ```JavaScript var launchModel = { title: "H5打开原生界面",//原生显示的标题 tag:"Main",// 页面标签,如果从其他界面返回到指定的界面就需要用到这个tag page: "https://m.baidu.com",//原生加载的H5地址 params: {// 需要传递过去的参数 param1: "value1", param2: "value2", param3: "value3" }, menus: [// 原生标题栏右侧的Menu菜单, { text: "添加",//菜单显示的文字 icon: "add"//菜单显示的图标 }, { text: "添加", icon: "search" } ] }; // 把JavaScript中的对象转换为json数据,在传给原生 var launchModelString = JSON.stringify(launchModel); // 打开原生新的界面 window.jsBridge.call("navigation", launchModelString); ``` * menus 最多能显示3个,多以3个,从第三个开始使用"...表示",理论上支持无限个menu。 * launchModel中的tag,字段为页面标签,如果从其他界面返回到指定的界面就需要用到这个tag,在不设置tag的情况下默认使用正在加载的H5地址作为tag。 * tag不能重复,如果当前界面堆栈列表中已经存在了一个被tag标记的界面,使用相同的tag不能再打开原生界面。 * 通过 navigation传递过去的params参数会在onNativeLoad回调 ```JavaScript //原生界面初始化完成时回调,相当于windows.onLoad但不等价 window.onNativeLoad = function (params) { console.log("-------->收到参数:" + params); }; ``` #### 3 打开原生界面,不保留原来界面"redirect" ```JavaScript var launchModel = { title: "redirect",//原生显示的标题 page: "http://10.8.10.15:8080/jsBridge2/jsBridge/MenuDemo.html",//原生加载的H5地址 params: { name: "张三", age: "23", sex: "男" }, menus: [ { text: "添加", icon: "add" }, { text: "搜索", icon: "search" } ] }; window.jsBridge.call("redirect", JSON.stringify(launchModel)); ``` * 如果现在原生界面的堆栈列表如下:A、B、C,在C界面调用redirect启动一个原生界面D时,现在堆栈列表为:A、B、D #### 4 打开原生界面,关闭其他所有的界面"redirect" ```JavaScript var launchModel = { title: "reLaunch",//原生显示的标题 page: "http://10.8.10.15:8080/jsBridge2/jsBridge/MenuDemo.html",//原生加载的H5地址 params: { name: "张三", age: "23", sex: "男" }, menus: [ { text: "添加", icon: "add" }, { text: "搜索", icon: "search" } ] }; window.jsBridge.call("reLaunch", JSON.stringify(launchModel)); ``` * 如果现在原生界面的堆栈列表如下:A、B、C,在C界面调用reLaunch启动一个原生界面D时,现在堆栈列表为:D #### 5 关闭原生界面,并返回参数到上一个界面 "navigateBack" ```JavaScript //直接关闭不返回参数到上一个界面 window.jsBridge.call("navigateBack"); //关闭页面并传递参数到上一个界面 var params = {//需要传递给上一个界面的参数 param1: "value1", param2: "value2", param3: "value3" } // 把JavaScript中的对象转换为json数据,在传给原生 var paramsString = JSON.stringify(params); //关闭界面 window.jsBridge.call("navigateBack",paramsString); ``` 通过navigateBack或者navigateBackByTag返回的参数会在上一个界面的onNativeResult函数回调 ```JavaScript // 接收上一个界面传递过来的参数 window.onNativeResult = function (params) { alert('收到上一个界面传递过来的参数:' + params); }; ``` 在关闭界面的时候不传递参数,上一个界面的onNativeResult不会回调,点击物理返回键(android)、标题栏返回键"🔙",上一个界面的onNativeResult不会回调 #### 6 通过tag关闭原生界面,并跳转到tag指定的界面 "navigateBackByTag" ```JavaScript //关闭页面并传递参数到上一个界面 var params = { tag: "Main", params: {// 需要返回到上一个界面的参数 param1: "value1", param2: "value2", param3: "value3" } } // 把JavaScript中的对象转换为json数据,在传给原生 var paramsString = JSON.stringify(params); //关闭界面 window.jsBridge.call("navigateBackByTag",paramsString); ``` * 如果调用navigateBackByTag通过Tag关闭指定的界面时,Tag对应的界面不存在时,不会返回任何界面,并系统有有Toast提示 #### 7 设置返回上一个参数"setResult" ```JavaScript window.jsBridge.call("setResult", JSON.stringify({ name: "张三", age: "23", sex: "男" })); ``` 通过setResult设置返回上一个界面参数后,无论是点击物理返回键(Android)、或者标题栏返回键"🔙"、调用navigateBack()原生界面关闭时都可以返回参数到上一页界面, 但是如果使用navigateBack(params)方式关闭原生界面,之前通过setResult设置的参数无效,上一个界面收到的参数为params具体的内容。 #### 8 H5监听原生的返回键"addBackListener" ```JavaScript jsBridge.call("addBackListener"); ``` H5调用原生的方法"addBackListener"就可以监听原生的返回键,当用户点击物理返回键、标题栏返回键"🔙"时回调onNativeBackListener ```JavaScript // 点击原生的返回键时回调 window.onNativeBackListener = function (text) { if (confirm("你确定要退出吗?")) { jsBridge.call("navigateBack"); } else { alert("点击了取消"); } } ``` 注意:只要H5监听返回键,原生不再处理返回键事件,也就是说H5监听返回键触发onNativeBackListener后H5不做处理就不能返回上一个界面。 #### 9 获取用户信息"getUserInfo" ```JavaScript jsBridge.call("getUserInfo", "", function (userInfo) { alert(userInfo); }) ``` 注意:jsBridge.call中的第二个参数必须传,否则无法获取用户信息,具体参数说明请查看"如何使用"中的第4点。 #### 10 动态添加标题栏menu菜单"addMenu" ```JavaScript window.jsBridge.call("addMenu", JSON.stringify( [ { text: "添加1", icon: "add" }, { text: "新增2", icon: "search" }, { text: "新增3", icon: "add" } ])); ``` 注意: 1.动态添加标题栏是在原来的基础上添加,也就是所如果现在有2个菜单项,现在又添加3个,现在原生界面一共显示5个菜单项。 2.添加menu的时候text不能重复(同一个界面) #### 11 动态移除标题栏menu菜单"removeMenu" ```JavaScript window.jsBridge.call("removeMenu", "搜索"); ``` 注意:意思是移除标题栏中的menu的text为"搜索"的菜单,如果不存在这样的菜单不做任何处理。 #### 12 动态移除标题栏所有菜单"removeAllMenu" ```JavaScript window.jsBridge.call("removeAllMenu"); ``` #### 13 从本地相册选择图片或使用相机拍照"chooseImages(Object object )" #### 参数 #### Object object | 属性 | 类型 | 默认值 |必填| 说明 | :------- | :------ | :----: |:----:|:----: | | count | number | 9 | 否 | 最多可以选择的图片张数 | | sizeType | Array\ | \['original', 'compressed'] | 否 | 所选的图片的尺寸 | | sourceType| Array\ | \['album', 'camera'] | 否 | 选择图片的来源 | | success| function | | 否 | 接口调用成功的回调函数 | | fail| function | | 否 | 接口调用失败的回调函数 | | complete| function | | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) | #### object.sizeType 的合法值 | 值 | 说明 | 最低版本 | | :------- | :------ | :----: | | original | 原图 | 1.1.0 | | compressed | 压缩图 | 1.1.0 | #### object.sourceType 的合法值 | 值 | 说明 | 最低版本 | | :------- | :------ | :----: | | album | 从相册选图 | 1.1.0 | | camera | 使用相机 | 1.1.0 | #### object.success 回调函数 #### Object res | 属性 | 类型 | 说明| | :------- | :------ | :----: | | tempFiles | Array\ | 图片的本地临时文件列表 | #### res.tempFiles 的结构 | 属性 | 类型 | 说明| | :------- | :------ | :----: | | path | String | 本地临时文件路径 | | size | number | 本地临时文件大小,单位 B | ```JavaScript jsBridge.chooseImage({ count:10, sizeType: ["compressed", "original"], sourceType: ["album", "camera"], success:function(res) { console.log("----------->图片选择成功"); console.log(res); console.log(res.tempFiles); res.tempFiles.forEach(function (element) { var path = element.path; var li = ''; li += '
  • '; li += ''; li += "
  • "; $("#mui22222").append(li); }); }, fail:function(res) { console.log("----------->图片选择失败!"); console.log(res) }, complete:function(res) { console.log("----------->完成 ok"); console.log(res) } }); ``` #### 14 把本地图片转Base64"imageToBase64(Object object )" #### 参数 #### Object object | 属性 | 类型 | 默认值 |必填| 说明 | :------- | :------ | :----: |:----:|:----: | | url | String | | 是 | 要转换的本地图片url,url必须是从chooseImages获取 | | quality | number | 80 | 否 | 转换的质量,值越大转换Base64越大 建议:10-100之间 | | success| function | | 否 | 接口调用成功的回调函数 | | fail| function | | 否 | 接口调用失败的回调函数 | | complete| function | | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) | #### object.success 回调函数 #### Object res | 属性 | 类型 | 说明| | :------- | :------ | :----: | | data | String | Base64数据,不带: `data:img/jpg;base64,` | ```JavaScript jsBridge.imageToBase64({ url:imageUrl, quality:30, success:function(res) { console.log(res); console.log("----------->图片转成功"); var li = ''; li += '
  • '; li += ''; li += "
  • "; $("#mui22222").append(li); }, fail:function(res) { console.log("----------->图片转失败"); console.log(res) }, complete:function(res) { console.log("----------->图片转完成"); console.log(res) } }); ``` #### 15 将本地资源上传到服务器"uploadFile(Object object )" #### 参数 #### Object object | 属性 | 类型 | 默认值 |必填| 说明 | :------- | :------ | :----: |:----:|:----: | | url | String | | 是 | 开发者服务器地址 | | filePath | String | | 是 | 要上传文件资源的路径 | | name | string | | 是 | 文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容 | | header | Object | | 否 | HTTP 请求 Header | | formData | Object | | 否 | HTTP 请求中其他额外的 form data | | success| function | | 否 | 接口调用成功的回调函数 | | fail| function | | 否 | 接口调用失败的回调函数 | | complete| function | | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) | #### object.success 回调函数 #### Object res | 属性 | 类型 | 说明| | :------- | :------ | :----: | | data | String | 开发者服务器返回的数据 | | statusCode | number | 开发者服务器返回的 HTTP 状态码 | ```JavaScript jsBridge.uploadFile({ url:"http://10.18.15.58:8002/cloudec/storage/upload/front/upfile", filePath:localFile, name:"test", header:{ jwt:"3333333", name:"sdfsdfsdfds" }, formData:{ age:123, userId:"123455" }, success: function (res) { mui.toast("图片上传成功"); }, fail: function (res) { mui.toast("图片上传失败"); console.log(res) } }); ``` #### 16 调起客户端扫码界面进行扫码"scanCode(Object object)" #### 参数 #### Object object | 属性 | 类型 | 默认值 |必填| 说明 | :------- | :------ | :----: |:----:|:----: | | onlyFromCamera | boolean | false | 否 | 是否只能从相机扫码,不允许从相册选择图片 | | scanType | `Array.` | `['barCode', 'qrCode']` | 否 | 扫码类型 | | success| function | | 否 | 接口调用成功的回调函数 | | fail| function | | 否 | 接口调用失败的回调函数 | | complete| function | | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) | #### object.scanType 的合法值 | 值 | 说明 | 最低版本| | :------- | :----: | :----- | | barCode | 一维码 | 1.2.0 | | qrCode | 二维码 | 1.2.0 | #### object.success 回调函数 #### Object res | 属性 | 类型 | 说明| | :------- | :------ | :----: | | result | String | 所扫码的内容 | | scanType | String | 所扫码的类型 | #### res.scanType 的合法值 | 值 | 说明 | 最低版本| | :------- | :----: | :----- | | QR_CODE | 一维码 | 1.2.0 | | AZTEC | 一维码 | 1.2.0 | | CODABAR | 一维码 | 1.2.0 | | CODE_39 | 一维码 | 1.2.0 | | CODE_93 | 一维码 | 1.2.0 | | CODE_128 | 一维码 | 1.2.0 | | DATA_MATRIX | 二维码 | 1.2.0 | | EAN_8 | 一维码 | 1.2.0 | | EAN_13 | 一维码 | 1.2.0 | | ITF | 一维码 | 1.2.0 | | MAXICODE | 一维码 | 1.2.0 | | PDF_417 | 二维码 | 1.2.0 | | RSS_14 | 一维码 | 1.2.0 | | RSS_EXPANDED | 一维码 | 1.2.0 | | UPC_A | 一维码 | 1.2.0 | | UPC_E | 一维码 | 1.2.0 | | UPC_EAN_EXTENSION | 一维码 | 1.2.0 | | CODE_25 | 一维码 | 1.2.0 | ```JavaScript // 允许从相机和相册扫码 jsBridge.scanCode({ success:function(res){ buildDoc('扫描成功:'+JSON.stringify(res)); }, fail:function(res){ buildDoc('扫描失败:'+JSON.stringify(res)); }, complete:function(res){ buildDoc('扫描完成:'+JSON.stringify(res)); } }); // 只允许从相机扫码 jsBridge.scanCode({ onlyFromCamera: true, success:function(res){ buildDoc('扫描成功:'+JSON.stringify(res)); }, fail:function(res){ buildDoc('扫描失败:'+JSON.stringify(res)); }, complete:function(res){ buildDoc('扫描完成:'+JSON.stringify(res)); } }); ```