1. // 本文来自: https://github.com/AlanZhang001/H5CallUpNative (具体详情信息请转此处)
    2. <script src="https://code.jquery.com/jquery-1.10.2.js"></script> 或 // var extend = require('extend');
    3. <script>
    4. var browser = {
    5. isAndroid: function () {
    6. return navigator.userAgent.match(/Android/i) ? true : false;
    7. },
    8. isMobileQQ: function () {
    9. var ua = navigator.userAgent;
    10. return /(iPad|iPhone|iPod).*? (IPad)?QQ\/([\d\.]+)/.test(ua) || /\bV1_AND_SQI?_([\d\.]+)(.*? QQ\/([\d\.]+))?/
    11. .test(ua);
    12. },
    13. isIOS: function () {
    14. return navigator.userAgent.match(/iPhone|iPad|iPod/i) ? true : false;
    15. },
    16. isWx: function () {
    17. return navigator.userAgent.match(/micromessenger/i) ? true : false;
    18. },
    19. isChrome: function () {
    20. return (navigator.userAgent.match(/Chrome\/([\d.]+)/) || navigator.userAgent.match(/CriOS\/([\d.]+)/)) ? true :
    21. false;
    22. },
    23. isBaidu: function () {
    24. return navigator.userAgent.match(/baidubrowser/i) ? true : false;
    25. },
    26. isUC: function () {
    27. return navigator.userAgent.match(/UCBrowser/i) ? true : false;
    28. },
    29. isSafari: function () {
    30. return navigator.userAgent.match(/safari/i) ? true : false;
    31. },
    32. isQQBrowser: function () {
    33. return navigator.userAgent.match(/MQQBrowser/i) ? true : false;
    34. },
    35. isWeibo: function () {
    36. return navigator.userAgent.match(/weibo/i) ? true : false;
    37. },
    38. isAlipay: function () {
    39. return navigator.userAgent.match(/Alipay/i) ? true : false;
    40. }
    41. };
    42. /**
    43. * [defautlConfig APP默认配置]
    44. */
    45. var defautlConfig = {
    46. // 协议头
    47. PROTOCAL: '',
    48. // 主页
    49. HOME: '',
    50. // 唤起失败时的跳转链接
    51. FAILBACK: {
    52. ANDROID: '',
    53. IOS: ''
    54. },
    55. // Android apk 相关信息
    56. APK_INFO: {
    57. PKG: '',
    58. CATEGORY: 'android.intent.category.DEFAULT',
    59. ACTION: 'android.intent.action.VIEW'
    60. },
    61. // 唤起超时时间,超时则跳转到下载页面
    62. LOAD_WAITING: 3000
    63. };
    64. /**
    65. * [util 创建A标签]
    66. */
    67. var util = {
    68. hiddenStyle: 'display:none;width:0px;height:0px;',
    69. /**
    70. * [createIfr 创建iframe并隐藏,未加入document中]
    71. */
    72. createIfr: function (src) {
    73. var iframe = document.createElement('iframe');
    74. iframe.className = 'call_up_iframe';
    75. iframe.src = src;
    76. iframe.style.cssText = this.hiddenStyle;
    77. return iframe;
    78. },
    79. /**
    80. * [createALink 创建A标签并隐藏,未加入document中]
    81. */
    82. createALink: function (href) {
    83. var aLink = document.createElement("a");
    84. aLink.className = 'call_up_a_link';
    85. aLink.href = href;
    86. aLink.style.cssText = this.hiddenStyle;
    87. return aLink;
    88. },
    89. /**
    90. * [isDocHidden docuement是否已隐藏]
    91. */
    92. isDocHidden: function () {
    93. return document.hidden || document.webkitHidden || document.msHidden;
    94. },
    95. /**
    96. * [visibilityChangeName 兼容visibilityChange]
    97. */
    98. visibilityChangeName: function () {
    99. var visibilityChange;
    100. if (typeof document.hidden !== 'undefined') {
    101. visibilityChange = 'visibilitychange';
    102. } else if (typeof document.msHidden !== 'undefined') {
    103. visibilityChange = 'msvisibilitychange';
    104. } else if (typeof document.webkitHidden !== 'undefined') {
    105. visibilityChange = 'webkitvisibilitychange';
    106. };
    107. return visibilityChange;
    108. }
    109. };
    110. function Callup(config) {
    111. if (!config) {
    112. return;
    113. };
    114. // 合并参数
    115. this.appConfig = $.extend({}, defautlConfig, config, true);
    116. };
    117. $.extend(Callup.prototype, {
    118. /**
    119. * [generateSchema 根据不同的场景及UA生成最终应用的schema]
    120. */
    121. generateSchema: function (schemaURI) {
    122. var schemaStr = '';
    123. // 如果未定义schema,则根据当前路径来映射
    124. if (!schemaURI) {
    125. schemaStr = this.appConfig.HOME;
    126. // 在schema省略时,可以根据当前页面的url,设置不同的默认值
    127. } else {
    128. schemaStr = schemaURI;
    129. };
    130. // 如果是安卓chrome浏览器,则通过intent方式打开
    131. // if (browser.isChrome() && browser.isAndroid() && browser.isUC() === false && browser.isQQBrowser() ===
    132. // false) {
    133. // schemaStr = 'intent://' + schemaStr + '#Intent;' +
    134. // 'scheme=' + this.appConfig.PROTOCAL + ';' +
    135. // 'package=' + this.appConfig.APK_INFO.PKG + ';' +
    136. // 'category=' + this.appConfig.APK_INFO.CATEGORY + ';' +
    137. // 'action=' + this.appConfig.APK_INFO.ACTION + ';' +
    138. // 'S.browser_fallback_url=' + encodeURIComponent(this.appConfig.FAILBACK.ANDROID) + ';' +
    139. // 'end';
    140. // } else {
    141. // schemaStr = this.appConfig.PROTOCAL + '://' + schemaStr;
    142. // };
    143. //直接打开
    144. schemaStr = this.appConfig.PROTOCAL + '://' + schemaStr;
    145. return schemaStr;
    146. },
    147. /**
    148. * [loadSchema 加载schema,打开app]
    149. */
    150. loadSchema: function (config) {
    151. // 需要使用的schema
    152. var schemaUrl = this.generateSchema(config.targetURI);
    153. var body = document.body;
    154. // Android 微信不支持schema唤醒,必须提前加入腾讯的白名单
    155. // 百度浏览器会拦截schema,所以直接跳下载页
    156. // QQ,weobo 内也直接跳转下载页
    157. if (browser.isWx() || browser.isBaidu() ||
    158. (browser.isIOS() && browser.isMobileQQ()) ||
    159. (browser.isIOS() && browser.isAlipay()) ||
    160. browser.isWeibo()) {
    161. if (browser.isAndroid()) {
    162. window.location.href = this.appConfig.FAILBACK.ANDROID;
    163. } else if (browser.isIOS()) {
    164. window.location.href = this.appConfig.FAILBACK.IOS;
    165. };
    166. // Android chrome 不支持iframe 方式唤醒
    167. // 适用:chrome,leibao,mibrowser,opera,360,UC,qq浏览器
    168. } else if (browser.isChrome() && browser.isAndroid() ||
    169. browser.isUC() ||
    170. browser.isSafari() ||
    171. browser.isQQBrowser()) {
    172. var aLink = util.createALink(schemaUrl); // 创建
    173. body.appendChild(aLink);
    174. aLink.click();
    175. // 其他浏览器
    176. // 适用:sogou,firefox,mobileQQ
    177. } else {
    178. var iframe = util.createIfr(schemaUrl);
    179. body.appendChild(iframe);
    180. };
    181. this.checkLoadStatus(config.success, config.fail);
    182. },
    183. /**
    184. * [checkLoadStatus 通过setTimeout来检查App是否启动]
    185. */
    186. checkLoadStatus: function (success, fail) {
    187. var start = new Date().getTime();
    188. var that = this;
    189. var loadTimer = setTimeout(function () {
    190. if (util.isDocHidden()) {
    191. return;
    192. };
    193. // 如果app启动,浏览器最小化进入后台,则计时器存在推迟或者变慢的问题
    194. // 那么代码执行到此处时,时间间隔必然大于设置的定时时间
    195. if (Date.now() - start > that.appConfig.LOAD_WAITING + 200) {
    196. //console.log('come back from app')
    197. // 如果浏览器未因为app启动进入后台,则定时器会准时执行,故应该跳转到下载页
    198. } else {
    199. if (fail) {
    200. fail();
    201. } else {
    202. window.location.href = browser.isIOS() ? that.appConfig.FAILBACK.IOS : that.appConfig.FAILBACK.ANDROID;
    203. };
    204. };
    205. }, this.appConfig.LOAD_WAITING);
    206. // 当本地app被唤起,则页面会隐藏掉,就会触发pagehide与visibilitychange事件
    207. // 在部分浏览器中可行,网上提供方案,作hack处理
    208. document.addEventListener(util.visibilityChangeName(), function () {
    209. if (util.isDocHidden) {
    210. clearTimeout(loadTimer);
    211. }
    212. }, false);
    213. // pagehide 必须绑定到window
    214. window.addEventListener('pagehide', function () {
    215. clearTimeout(loadTimer);
    216. success && success();
    217. }, false);
    218. }
    219. });
    220. /*globals Callup*/
    221. var callup = new Callup({
    222. // 协议头
    223. PROTOCAL: 'shareits',
    224. // 主页
    225. HOME: 'game',
    226. // 唤起失败时的跳转链接
    227. FAILBACK: {
    228. ANDROID: 'https://play.google.com/store/apps/details?id=com.lenovo.anyshare.gps&referrer=utm_source%3D%26utm_medium%3DSHAREitinvite%26utm_campaign%3Dinvite',
    229. IOS: ''
    230. },
    231. // Android apk 相关信息
    232. APK_INFO: {
    233. PKG: 'com.lenovo.anyshare',
    234. CATEGORY: 'android.intent.category.DEFAULT',
    235. ACTION: 'android.intent.action.VIEW'
    236. },
    237. // 唤起超时时间,超时则跳转到下载页面
    238. LOAD_WAITING: 2000
    239. });
    240. function action() {
    241. //encodeURIComponent()编码之后不会跳转到目的地,这里未使用编码
    242. // var url = encodeURIComponent('gameshare/8?inner_func_type=28&portal=gameshare&main_tab_name=navi_game&channel_id=game');
    243. var url = 'gameshare/8?inner_func_type=28&portal=gameshare&main_tab_name=navi_game&channel_id=game';
    244. callup.loadSchema({
    245. // 通过NN打开某个链接
    246. targetURI: url,
    247. success:function(){
    248. },
    249. fail: function(){
    250. window.location.href = 'https://play.google.com/store/apps/details?id=com.lenovo.anyshare.gps&referrer=utm_source%3D%26utm_medium%3DSHAREitinvite%26utm_campaign%3Dinvite';
    251. }
    252. });
    253. };
    254. window.onload = function() {
    255. // action();
    256. };
    257. </script>