1 /**!

2 * 微信内置浏览器的Javascript API,功能包括:

3 *

4 * 1、分享到微信朋友圈

5 * 2、分享给微信好友

6 * 3、分享到腾讯微博

7 * 4、新的分享接口,包含朋友圈、好友、微博的分享(for iOS)

8 * 5、隐藏/显示右上角的菜单入口

9 * 6、隐藏/显示底部浏览器工具栏

10 * 7、获取当前的网络状态

11 * 8、调起微信客户端的图片播放组件

12 * 9、关闭公众平台Web页面

13 * 10、判断当前网页是否在微信内置浏览器中打开

14 * 11、增加打开扫描二维码

15 * 12、支持WeixinApi的错误监控

16 * 13、检测应用程序是否已经安装(需要官方开通权限)

17 * 14、发送电子邮件

18 * 15、禁止用户分享

19 *

20 * @author guanguoxiang(http://www.ggxapp.com)

21 */

22 (function (window) {

23

24 "use strict";

25

26 /**

27 * 定义WeixinApi

28 */

29 var WeixinApi = {

30 version: 4.1

31 };

32

33 // 将WeixinApi暴露到window下:全局可使用,对旧版本向下兼容

34 window.WeixinApi = WeixinApi;

35

36 /////////////////////////// CommonJS /////////////////////////////////

37 if (typeof define === 'function' && (define.amd || define.cmd)) {

38 if (define.amd) {

39 // AMD 规范,for:requirejs

40 define(function () {

41 return WeixinApi;

42 });

43 } else if (define.cmd) {

44 // CMD 规范,for:seajs

45 define(function (require, exports, module) {

46 module.exports = WeixinApi;

47 });

48 }

49 }

50

51 /**

52 * 对象简单继承,后面的覆盖前面的,继承深度:deep=1

53 * @private

54 */

55 var _extend = function () {

56 var result = {}, obj, k;

57 for (var i = 0, len = arguments.length; i < len; i++) {

58 obj = arguments[i];

59 if (typeof obj === 'object') {

60 for (k in obj) {

61 obj[k] && (result[k] = obj[k]);

62 }

63 }

64 }

65 return result;

66 };

67

68 /**

69 * 内部私有方法,分享用

70 * @private

71 */

72 var _share = function (cmd, data, callbacks) {

73 callbacks = callbacks || {};

74

75 // 分享过程中的一些回调

76 var progress = function (resp) {

77 switch (true) {

78 // 用户取消

79 case /\:cancel$/i.test(resp.err_msg) :

80 callbacks.cancel && callbacks.cancel(resp);

81 break;

82 // 发送成功

83 case /\:(confirm|ok)$/i.test(resp.err_msg):

84 callbacks.confirm && callbacks.confirm(resp);

85 break;

86 // fail 发送失败

87 case /\:fail$/i.test(resp.err_msg) :

88 default:

89 callbacks.fail && callbacks.fail(resp);

90 break;

91 }

92 // 无论成功失败都会执行的回调

93 callbacks.all && callbacks.all(resp);

94 };

95

96 // 执行分享,并处理结果

97 var handler = function (theData, argv) {

98

99 // 加工一下数据

100 if (cmd.menu == 'menu:share:timeline' ||

101 (cmd.menu == 'general:share' && argv.shareTo == 'timeline')) {

102

103 var title = theData.title;

104 theData.title = theData.desc || title;

105 theData.desc = title || theData.desc;

106 }

107

108 // 新的分享接口,单独处理

109 if (cmd.menu === 'general:share') {

110 // 如果是收藏操作,并且在wxCallbacks中配置了favorite为false,则不执行回调

111 if (argv.shareTo == 'favorite' || argv.scene == 'favorite') {

112 if (callbacks.favorite === false) {

113 return argv.generalShare(theData, function () {

114 });

115 }

116 }

117 if (argv.shareTo === 'timeline') {

118 WeixinJSBridge.invoke('shareTimeline', theData, progress);

119 } else if (argv.shareTo === 'friend') {

120 WeixinJSBridge.invoke('sendAppMessage', theData, progress);

121 } else if (argv.shareTo === 'QQ') {

122 WeixinJSBridge.invoke('shareQQ', theData, progress);

123 }else if (argv.shareTo === 'weibo') {

124 WeixinJSBridge.invoke('shareWeibo', theData, progress);

125 }

126 } else {

127 WeixinJSBridge.invoke(cmd.action, theData, progress);

128 }

129 };

130

131 // 监听分享操作

132 WeixinJSBridge.on(cmd.menu, function (argv) {

133 callbacks.dataLoaded = callbacks.dataLoaded || new Function();

134 if (callbacks.async && callbacks.ready) {

135 WeixinApi["_wx_loadedCb_"] = callbacks.dataLoaded;

136 if (WeixinApi["_wx_loadedCb_"].toString().indexOf("_wx_loadedCb_") > 0) {

137 WeixinApi["_wx_loadedCb_"] = new Function();

138 }

139 callbacks.dataLoaded = function (newData) {

140 callbacks.__cbkCalled = true;

141 var theData = _extend(data, newData);

142 theData.img_url = theData.imgUrl || theData.img_url;

143 delete theData.imgUrl;

144 WeixinApi["_wx_loadedCb_"](theData);

145 handler(theData, argv);

146 };

147 // 然后就绪

148 if (!(argv && (argv.shareTo == 'favorite' || argv.scene == 'favorite') && callbacks.favorite === false)) {

149 callbacks.ready && callbacks.ready(argv, data);

150 // 如果设置了async为true,但是在ready方法中并没有手动调用dataLoaded方法,则自动触发一次

151 if (!callbacks.__cbkCalled) {

152 callbacks.dataLoaded({});

153 callbacks.__cbkCalled = false;

154 }

155 }

156 } else {

157 // 就绪状态

158 var theData = _extend(data);

159 if (!(argv && (argv.shareTo == 'favorite' || argv.scene == 'favorite') && callbacks.favorite === false)) {

160 callbacks.ready && callbacks.ready(argv, theData);

161 }

162 handler(theData, argv);

163 }

164 });

165 };

166

167 /**

168 * 分享到微信朋友圈

169 * @param {Object} data 待分享的信息

170 * @p-config {String} appId 公众平台的appId(服务号可用)

171 * @p-config {String} imgUrl 图片地址

172 * @p-config {String} link 链接地址

173 * @p-config {String} desc 描述

174 * @p-config {String} title 分享的标题

175 *

176 * @param {Object} callbacks 相关回调方法

177 * @p-config {Boolean} async ready方法是否需要异步执行,默认false

178 * @p-config {Function} ready(argv, data) 就绪状态

179 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空

180 * @p-config {Function} cancel(resp) 取消

181 * @p-config {Function} fail(resp) 失败

182 * @p-config {Function} confirm(resp) 成功

183 * @p-config {Function} all(resp) 无论成功失败都会执行的回调

184 */

185 WeixinApi.shareToTimeline = function (data, callbacks) {

186 _share({

187 menu: 'menu:share:timeline',

188 action: 'shareTimeline'

189 }, {

190 "appid": data.appId ? data.appId : '',

191 "img_url": data.imgUrl,

192 "link": data.link,

193 "desc": data.desc,

194 "title": data.title,

195 "img_width": "640",

196 "img_height": "640"

197 }, callbacks);

198 };

199

200 /**

201 * 发送给微信上的好友

202 * @param {Object} data 待分享的信息

203 * @p-config {String} appId 公众平台的appId(服务号可用)

204 * @p-config {String} imgUrl 图片地址

205 * @p-config {String} link 链接地址

206 * @p-config {String} desc 描述

207 * @p-config {String} title 分享的标题

208 *

209 * @param {Object} callbacks 相关回调方法

210 * @p-config {Boolean} async ready方法是否需要异步执行,默认false

211 * @p-config {Function} ready(argv, data) 就绪状态

212 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空

213 * @p-config {Function} cancel(resp) 取消

214 * @p-config {Function} fail(resp) 失败

215 * @p-config {Function} confirm(resp) 成功

216 * @p-config {Function} all(resp) 无论成功失败都会执行的回调

217 */

218 WeixinApi.shareToFriend = function (data, callbacks) {

219 _share({

220 menu: 'menu:share:appmessage',

221 action: 'sendAppMessage'

222 }, {

223 "appid": data.appId ? data.appId : '',

224 "img_url": data.imgUrl,

225 "link": data.link,

226 "desc": data.desc,

227 "title": data.title,

228 "img_width": "640",

229 "img_height": "640"

230 }, callbacks);

231 };

232

233

234 /**

235 * 分享到腾讯微博

236 * @param {Object} data 待分享的信息

237 * @p-config {String} link 链接地址

238 * @p-config {String} desc 描述

239 *

240 * @param {Object} callbacks 相关回调方法

241 * @p-config {Boolean} async ready方法是否需要异步执行,默认false

242 * @p-config {Function} ready(argv, data) 就绪状态

243 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空

244 * @p-config {Function} cancel(resp) 取消

245 * @p-config {Function} fail(resp) 失败

246 * @p-config {Function} confirm(resp) 成功

247 * @p-config {Function} all(resp) 无论成功失败都会执行的回调

248 */

249 WeixinApi.shareToWeibo = function (data, callbacks) {

250 _share({

251 menu: 'menu:share:weibo',

252 action: 'shareWeibo'

253 }, {

254 "content": data.desc,

255 "url": data.link

256 }, callbacks);

257 };

258

259 /**

260 * 新的分享接口

261 * @param {Object} data 待分享的信息

262 * @p-config {String} appId 公众平台的appId(服务号可用)

263 * @p-config {String} imgUrl 图片地址

264 * @p-config {String} link 链接地址

265 * @p-config {String} desc 描述

266 * @p-config {String} title 分享的标题

267 *

268 * @param {Object} callbacks 相关回调方法

269 * @p-config {Boolean} async ready方法是否需要异步执行,默认false

270 * @p-config {Function} ready(argv, data) 就绪状态

271 * @p-config {Function} dataLoaded(data) 数据加载完成后调用,async为true时有用,也可以为空

272 * @p-config {Function} cancel(resp) 取消

273 * @p-config {Function} fail(resp) 失败

274 * @p-config {Function} confirm(resp) 成功

275 * @p-config {Function} all(resp) 无论成功失败都会执行的回调

276 */

277 WeixinApi.generalShare = function (data, callbacks) {

278 _share({

279 menu: 'general:share'

280 }, {

281 "appid": data.appId ? data.appId : '',

282 "img_url": data.imgUrl,

283 "link": data.link,

284 "desc": data.desc,

285 "title": data.title,

286 "img_width": "640",

287 "img_height": "640"

288 }, callbacks);

289 };

290

291 /**

292 * 设置页面禁止分享:包括朋友圈、好友、腾讯微博、qq

293 * @param callback

294 */

295 WeixinApi.disabledShare = function (callback) {

296 callback = callback || function () {

297 alert('当前页面禁止分享!');

298 };

299 ['menu:share:timeline', 'menu:share:appmessage', 'menu:share:qq',

300 'menu:share:weibo', 'general:share'].forEach(function (menu) {

301 WeixinJSBridge.on(menu, function () {

302 callback();

303 return false;

304 });

305 });

306 };

307

308 /**

309 * 加关注(此功能只是暂时先加上,不过因为权限限制问题,不能用,如果你的站点是部署在*.qq.com下,也许可行)

310 * @param {String} appWeixinId 微信公众号ID

311 * @param {Object} callbacks 回调方法

312 * @p-config {Function} fail(resp) 失败

313 * @p-config {Function} confirm(resp) 成功

314 */

315 WeixinApi.addContact = function (appWeixinId, callbacks) {

316 callbacks = callbacks || {};

317 WeixinJSBridge.invoke("addContact", {

318 webtype: "1",

319 username: appWeixinId

320 }, function (resp) {

321 var success = !resp.err_msg || "add_contact:ok" == resp.err_msg

322 || "add_contact:added" == resp.err_msg;

323 if (success) {

324 callbacks.success && callbacks.success(resp);

325 } else {

326 callbacks.fail && callbacks.fail(resp);

327 }

328 })

329 };

330

331 /**

332 * 调起微信Native的图片播放组件。

333 * 这里必须对参数进行强检测,如果参数不合法,直接会导致微信客户端crash

334 *

335 * @param {String} curSrc 当前播放的图片地址

336 * @param {Array} srcList 图片地址列表

337 */

338 WeixinApi.imagePreview = function (curSrc, srcList) {

339 if (!curSrc || !srcList || srcList.length == 0) {

340 return;

341 }

342 WeixinJSBridge.invoke('imagePreview', {

343 'current': curSrc,

344 'urls': srcList

345 });

346 };

347

348 /**

349 * 显示网页右上角的按钮

350 */

351 WeixinApi.showOptionMenu = function () {

352 WeixinJSBridge.call('showOptionMenu');

353 };

354

355

356 /**

357 * 隐藏网页右上角的按钮

358 */

359 WeixinApi.hideOptionMenu = function () {

360 WeixinJSBridge.call('hideOptionMenu');

361 };

362

363 /**

364 * 显示底部工具栏

365 */

366 WeixinApi.showToolbar = function () {

367 WeixinJSBridge.call('showToolbar');

368 };

369

370 /**

371 * 隐藏底部工具栏

372 */

373 WeixinApi.hideToolbar = function () {

374 WeixinJSBridge.call('hideToolbar');

375 };

376

377 /**

378 * 返回如下几种类型:

379 *

380 * network_type:wifi wifi网络

381 * network_type:edge 非wifi,包含3G/2G

382 * network_type:fail 网络断开连接

383 * network_type:wwan 2g或者3g

384 *

385 * 使用方法:

386 * WeixinApi.getNetworkType(function(networkType){

387 *

388 * });

389 *

390 * @param callback

391 */

392 WeixinApi.getNetworkType = function (callback) {

393 if (callback && typeof callback == 'function') {

394 WeixinJSBridge.invoke('getNetworkType', {}, function (e) {

395 // 在这里拿到e.err_msg,这里面就包含了所有的网络类型

396 callback(e.err_msg);

397 });

398 }

399 };

400

401 /**

402 * 关闭当前微信公众平台页面

403 * @param {Object} callbacks 回调方法

404 * @p-config {Function} fail(resp) 失败

405 * @p-config {Function} success(resp) 成功

406 */

407 WeixinApi.closeWindow = function (callbacks) {

408 callbacks = callbacks || {};

409 WeixinJSBridge.invoke("closeWindow", {}, function (resp) {

410 switch (resp.err_msg) {

411 // 关闭成功

412 case 'close_window:ok':

413 callbacks.success && callbacks.success(resp);

414 break;

415

416 // 关闭失败

417 default :

418 callbacks.fail && callbacks.fail(resp);

419 break;

420 }

421 });

422 };

423

424 /**

425 * 当页面加载完毕后执行,使用方法:

426 * WeixinApi.ready(function(Api){

427 * // 从这里只用Api即是WeixinApi

428 * });

429 * @param readyCallback

430 */

431 WeixinApi.ready = function (readyCallback) {

432

433 /**

434 * 加一个钩子,同时解决Android和iOS下的分享问题

435 * @private

436 */

437 var _hook = function () {

438 var _WeixinJSBridge = {};

439 Object.keys(WeixinJSBridge).forEach(function (key) {

440 _WeixinJSBridge[key] = WeixinJSBridge[key];

441 });

442 Object.keys(WeixinJSBridge).forEach(function (key) {

443 if (typeof WeixinJSBridge[key] === 'function') {

444 WeixinJSBridge[key] = function () {

445 try {

446 var args = arguments.length > 0 ? arguments[0] : {},

447 runOn3rd_apis = args.__params ? args.__params.__runOn3rd_apis || [] : [];

448 ['menu:share:timeline', 'menu:share:appmessage', 'menu:share:weibo',

449 'menu:share:qq', 'general:share'].forEach(function (menu) {

450 runOn3rd_apis.indexOf(menu) === -1 && runOn3rd_apis.push(menu);

451 });

452 } catch (e) {

453 }

454 return _WeixinJSBridge[key].apply(WeixinJSBridge, arguments);

455 };

456 }

457 });

458 };

459

460 if (readyCallback && typeof readyCallback == 'function') {

461 var Api = this;

462 var wxReadyFunc = function () {

463 _hook();

464 readyCallback(Api);

465 };

466 if (typeof window.WeixinJSBridge == "undefined") {

467 if (document.addEventListener) {

468 document.addEventListener('WeixinJSBridgeReady', wxReadyFunc, false);

469 } else if (document.attachEvent) {

470 document.attachEvent('WeixinJSBridgeReady', wxReadyFunc);

471 document.attachEvent('onWeixinJSBridgeReady', wxReadyFunc);

472 }

473 } else {

474 wxReadyFunc();

475 }

476 }

477 };

478

479 /**

480 * 判断当前网页是否在微信内置浏览器中打开

481 */

482 WeixinApi.openInWeixin = function () {

483 return /MicroMessenger/i.test(navigator.userAgent);

484 };

485

486 /*

487 * 打开扫描二维码

488 * @param {Object} callbacks 回调方法

489 * @p-config {Boolean} needResult 是否直接获取分享后的内容

490 * @p-config {String} desc 扫描二维码时的描述

491 * @p-config {Function} fail(resp) 失败

492 * @p-config {Function} success(resp) 成功

493 */

494 WeixinApi.scanQRCode = function (callbacks) {

495 callbacks = callbacks || {};

496 WeixinJSBridge.invoke("scanQRCode", {

497 needResult: callbacks.needResult ? 1 : 0,

498 desc: callbacks.desc || 'WeixinApi Desc'

499 }, function (resp) {

500 switch (resp.err_msg) {

501 // 打开扫描器成功

502 case 'scanQRCode:ok':

503 case 'scan_qrcode:ok':

504 callbacks.success && callbacks.success(resp);

505 break;

506

507 // 打开扫描器失败

508 default :

509 callbacks.fail && callbacks.fail(resp);

510 break;

511 }

512 });

513 };

514

515 /**

516 * 检测应用程序是否已安装

517 * by mingcheng 2014-10-17

518 *

519 * @param {Object} data 应用程序的信息

520 * @p-config {String} packageUrl 应用注册的自定义前缀,如 xxx:// 就取 xxx

521 * @p-config {String} packageName 应用的包名

522 *

523 * @param {Object} callbacks 相关回调方法

524 * @p-config {Function} fail(resp) 失败

525 * @p-config {Function} success(resp) 成功,如果有对应的版本信息,则写入到 resp.version 中

526 * @p-config {Function} all(resp) 无论成功失败都会执行的回调

527 */

528 WeixinApi.getInstallState = function (data, callbacks) {

529 callbacks = callbacks || {};

530

531 WeixinJSBridge.invoke("getInstallState", {

532 "packageUrl": data.packageUrl || "",

533 "packageName": data.packageName || ""

534 }, function (resp) {

535 var msg = resp.err_msg, match = msg.match(/state:yes_?(.*)$/);

536 if (match) {

537 resp.version = match[1] || "";

538 callbacks.success && callbacks.success(resp);

539 } else {

540 callbacks.fail && callbacks.fail(resp);

541 }

542

543 callbacks.all && callbacks.all(resp);

544 });

545 };

546

547 /**

548 * 发送邮件

549 * @param {Object} data 邮件初始内容

550 * @p-config {String} subject 邮件标题

551 * @p-config {String} body 邮件正文

552 *

553 * @param {Object} callbacks 相关回调方法

554 * @p-config {Function} fail(resp) 失败

555 * @p-config {Function} success(resp) 成功

556 * @p-config {Function} all(resp) 无论成功失败都会执行的回调

557 */

558 WeixinApi.sendEmail = function (data, callbacks) {

559 callbacks = callbacks || {};

560 WeixinJSBridge.invoke("sendEmail", {

561 "title": data.subject,

562 "content": data.body

563 }, function (resp) {

564 if (resp.err_msg === 'send_email:sent') {

565 callbacks.success && callbacks.success(resp);

566 } else {

567 callbacks.fail && callbacks.fail(resp);

568 }

569 callbacks.all && callbacks.all(resp);

570 })

571 };

572

573 /**

574 * 开启Api的debug模式,比如出了个什么错误,能alert告诉你,而不是一直很苦逼的在想哪儿出问题了

575 * @param {Function} callback(error) 出错后的回调,默认是alert

576 */

577 WeixinApi.enableDebugMode = function (callback) {

578 /**

579 * @param {String} errorMessage 错误信息

580 * @param {String} scriptURI 出错的文件

581 * @param {Long} lineNumber 出错代码的行号

582 * @param {Long} columnNumber 出错代码的列号

583 */

584 window.onerror = function (errorMessage, scriptURI, lineNumber, columnNumber) {

585

586 // 有callback的情况下,将错误信息传递到options.callback中

587 if (typeof callback === 'function') {

588 callback({

589 message: errorMessage,

590 script: scriptURI,

591 line: lineNumber,

592 column: columnNumber

593 });

594 } else {

595 // 其他情况,都以alert方式直接提示错误信息

596 var msgs = [];

597 msgs.push("额,代码有错。。。");

598 msgs.push("\n错误信息:", errorMessage);

599 msgs.push("\n出错文件:", scriptURI);

600 msgs.push("\n出错位置:", lineNumber + '行,' + columnNumber + '列');

601 alert(msgs.join(''));

602 }

603 }

604 };

605

606 })(window);

精彩链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。