首页 > 代码库 > 专门用于微信公众平台的Javascript API

专门用于微信公众平台的Javascript API

  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 =http://www.mamicode.com/ _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 =http://www.mamicode.com/ _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方法是否需要异步执行,默认false178      * @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方法是否需要异步执行,默认false211      * @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方法是否需要异步执行,默认false242      * @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.link256         }, 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方法是否需要异步执行,默认false270      * @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      * 设置页面禁止分享:包括朋友圈、好友、腾讯微博、qq293      * @param callback294      */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     微信公众号ID311      * @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: appWeixinId320         }, function (resp) {321             var success = !resp.err_msg || "add_contact:ok" == resp.err_msg322                 || "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      * 这里必须对参数进行强检测,如果参数不合法,直接会导致微信客户端crash334      *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‘: srcList345         });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/2G382      * network_type:fail     网络断开连接383      * network_type:wwan     2g或者3g384      *385      * 使用方法:386      * WeixinApi.getNetworkType(function(networkType){387      *388      * });389      *390      * @param callback391      */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即是WeixinApi428      * });429      * @param readyCallback430      */431     WeixinApi.ready = function (readyCallback) {432 433         /**434          * 加一个钩子,同时解决Android和iOS下的分享问题435          * @private436          */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-17518      *519      * @param       {Object}    data               应用程序的信息520      * @p-config    {String}    packageUrl      应用注册的自定义前缀,如 xxx:// 就取 xxx521      * @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.body563         }, 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) 出错后的回调,默认是alert576      */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: columnNumber593                 });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);

 

专门用于微信公众平台的Javascript API