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);

专门用于微信公众平台的Javascript API的更多相关文章

  1. 微信公众平台通用接口API指南

    微信公众平台 通用接口 消息接口 开发模式 作者:方倍工作室原文:http://www.doucube.com/index.php?m=Article&a=show&id=5 微信公众 ...

  2. 微信公众平台消息接口API指南

    简介 微信公众平台消息接口为开发者提供了一种新的消息处理方式.微信公众平台消息接口为开发者提供与用户进行消息交互的能力.对于成功接入消息接口的微信公众账号,当用户发消息给公众号,微信公众平台服务器会使 ...

  3. 微信公众平台开发,API接入与推送事件(1)

    博客好久没有更新了,今天说说微信开发.微信开发的好多初学者都会又这样的迷惑,微信开发到底是什么?其实微信开发本质我和我们的网站开发没有太大的区别.我们常说的微信开发也就是公众号开,微信公众号分为三个类 ...

  4. 使用gson和httpclient呼叫微信公众平台API

    吐槽:微信api很无语.有一部分xml.有一部分json. 最近看如何调用微信公众平台json有关api更方便.终于找到了httpcliect和gson对. 假设你有一个更好的办法,请告诉我. 了解如 ...

  5. Django+wechatpy接入微信公众平台以及授权登录

    确定Django环境可以正常运行,环境搭建见:Linux 搭建Nginx+uwsgi+Django环境 安装 wechatpy[cryptography] sudo pip3 install wech ...

  6. 微信公众平台接口API

    <?php /** * Author: helen * CreateTime: 2015/12/9 20:14 * description: 微信公众平台接口API */ class Wecha ...

  7. 微信公众平台自定义菜单接口API指南

    微信公众平台开发模式自定义菜单接口API指南 简介 开发者获取使用凭证(如何获取凭证)后,可以使用该凭证对公众账号的自定义菜单进行创建.查询和删除等操作. 自定义菜单接口可实现以下类型按钮: clic ...

  8. 微信公众平台开发(免费云BAE+高效优雅的Python+网站开放的API)

    虽然校园App是个我认为的绝对的好主意,但最近有个也不错的营销+开发的模式出现:微信平台+固定域名服务器. 微信公众平台的运行模式不外两个: 一.机器人模式或称转发模式,将说话内容转发到服务器上完成, ...

  9. 微信公众平台Js API(WeixinApi)

    微信公众平台Js API(WeixinApi): https://github.com/zxlie/WeixinApi#user-content-3%E9%9A%90%E8%97%8F%E5%BA%9 ...

随机推荐

  1. MyBatis入门(四)---动态SQL

    一.创建数据库表 1.1.创建表 USE `mybatis`; /*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; C ...

  2. windows 7 下,如何统计某文件夹下 视频总时长

    由于项目需要,我需要给系统加权限,这真是一个让人头疼的问题,如果要每个业务方法都加上权限判断逻辑,那真的不敢想象是多么大的工作量,日后有变动的话,我会不会发疯? 所以我必须利用之前学到的AOP编程,在 ...

  3. 获取byte数组的实际使用长度

    背景:byte.length只能获取到初始化的byte数组长度,而不是实际使用的长度,因此想要获取到实际的使用长度只能靠其他方法实现. 方法一: public class ByteActualLeng ...

  4. !!!jQuery中事件绑定 推荐使用.delegate()或者live()

    jQuery中的.bind()..live()和.delegate()之间区别分析 参考:http://www.jb51.net/article/27309.htm DOM树   首先,可视化一个HM ...

  5. JavaScript Patterns 3.3 Patterns for Enforcing new

    When your constructor has something like  this.member and you invoke the constructor without  new,  ...

  6. 测试mysql的sql语句预编译效果

    玩Oracle的都比较关注shared pool,特别是library cache,在使用了绑定变量(预编译sql)之后确实能得到很大的性能提升.现在在转Mysql之后特别是innodb很多东西都还能 ...

  7. PHP递归创建多级目录(一道面试题的解题过程)

    今天看到一道面试题,要写出一个可以创建多级目录的函数: 我的第一个感觉就是用递归创建,具体思路如下: function Directory($dir){ if(is_dir($dir) || @mkd ...

  8. ffmpeg2.2在ubuntu下使用NDK编译——并在android工程下测试使用

    作者:wainiwann 出处:http://www.cnblogs.com/wainiwann/ 本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...

  9. MyEclipse 6.5 代码自动提示功能配置教程

    1. 打开MyEclipse 6.0.1,然后“window”→“Preferences” 2. 选择“java”,展开,“Editor”,选择“Content Assist”. 3. 选择“Cont ...

  10. 设计模式C#实现(七)——生成器模式

    生成器模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. UML类图: 构成: 1.Builder(接口/抽象类)定义了创建一个产品Product的各个部件的方法,返回创 ...