分类: javascript

  • WeixinApi.js

    /**!
     * 微信内置浏览器的Javascript API,功能包括:
     *
     * 1、分享到微信朋友圈
     * 2、分享给微信好友
     * 3、分享到腾讯微博
     * 4、隐藏/显示右上角的菜单入口
     * 5、隐藏/显示底部浏览器工具栏
     * 6、获取当前的网络状态
     * 7、调起微信客户端的图片播放组件
     *
     * @author zhaoxianlie(http://www.baidufe.com)
     */
    var WeixinApi = (function () {
    
        /**
         * 分享到微信朋友圈
         * @param       {Object}    data       待分享的信息
         * @p-config    {String}    appId      公众平台的appId(服务号可用)
         * @p-config    {String}    imageUrl   图片地址
         * @p-config    {String}    link       链接地址
         * @p-config    {String}    desc       描述
         * @p-config    {String}    title      分享的标题
         *
         * @param       {Object}    callbacks  相关回调方法
         * @p-config    {Boolean}   async                   ready方法是否需要异步执行,默认false
         * @p-config    {Function}  ready(argv)             就绪状态
         * @p-config    {Function}  dataLoaded(data)        数据加载完成后调用,async为true时有用,也可以为空
         * @p-config    {Function}  cancel(resp)    取消
         * @p-config    {Function}  fail(resp)      失败
         * @p-config    {Function}  confirm(resp)   成功
         * @p-config    {Function}  all(resp)       无论成功失败都会执行的回调
         */
        function weixinShareTimeline(data, callbacks) {
            callbacks = callbacks || {};
            var shareTimeline = function (theData) {
                WeixinJSBridge.invoke('shareTimeline', {
                    "appid":theData.appId ? theData.appId : '',
                    "img_url":theData.imgUrl,
                    "link":theData.link,
                    "desc":theData.title,
                    "title":theData.desc, // 注意这里要分享出去的内容是desc
                    "img_width":"120",
                    "img_height":"120"
                }, function (resp) {
                    switch (resp.err_msg) {
                        // share_timeline:cancel 用户取消
                        case 'share_timeline:cancel':
                            callbacks.cancel && callbacks.cancel(resp);
                            break;
                        // share_timeline:fail 发送失败
                        case 'share_timeline:fail':
                            callbacks.fail && callbacks.fail(resp);
                            break;
                        // share_timeline:confirm 发送成功
                        case 'share_timeline:confirm':
                        case 'share_timeline:ok':
                            callbacks.confirm && callbacks.confirm(resp);
                            break;
                    }
                    // 无论成功失败都会执行的回调
                    callbacks.all && callbacks.all(resp);
                });
            };
            WeixinJSBridge.on('menu:share:timeline', function (argv) {
                if (callbacks.async && callbacks.ready) {
                    if(!callbacks.__dataLoadedFuncInited) {
                        var loadedCb = callbacks.dataLoaded || new Function();
                        callbacks.dataLoaded = function (newData) {
                            loadedCb(newData);
                            shareTimeline(newData);
                        };
                        callbacks.__dataLoadedFuncInited = true;
                    }
                    // 然后就绪
                    callbacks.ready && callbacks.ready(argv);
                } else {
                    // 就绪状态
                    callbacks.ready && callbacks.ready(argv);
                    shareTimeline(data);
                }
            });
        }
    
        /**
         * 发送给微信上的好友
         * @param       {Object}    data       待分享的信息
         * @p-config    {String}    appId      公众平台的appId(服务号可用)
         * @p-config    {String}    imageUrl   图片地址
         * @p-config    {String}    link       链接地址
         * @p-config    {String}    desc       描述
         * @p-config    {String}    title      分享的标题
         *
         * @param       {Object}    callbacks  相关回调方法
         * @p-config    {Boolean}   async                   ready方法是否需要异步执行,默认false
         * @p-config    {Function}  ready(argv)             就绪状态
         * @p-config    {Function}  dataLoaded(data)        数据加载完成后调用,async为true时有用,也可以为空
         * @p-config    {Function}  cancel(resp)    取消
         * @p-config    {Function}  fail(resp)      失败
         * @p-config    {Function}  confirm(resp)   成功
         * @p-config    {Function}  all(resp)       无论成功失败都会执行的回调
         */
        function weixinSendAppMessage(data, callbacks) {
            callbacks = callbacks || {};
            var sendAppMessage = function (theData) {
                WeixinJSBridge.invoke('sendAppMessage', {
                    "appid":theData.appId ? theData.appId : '',
                    "img_url":theData.imgUrl,
                    "link":theData.link,
                    "desc":theData.desc,
                    "title":theData.title,
                    "img_width":"120",
                    "img_height":"120"
                }, function (resp) {
                    switch (resp.err_msg) {
                        // send_app_msg:cancel 用户取消
                        case 'send_app_msg:cancel':
                            callbacks.cancel && callbacks.cancel(resp);
                            break;
                        // send_app_msg:fail 发送失败
                        case 'send_app_msg:fail':
                            callbacks.fail && callbacks.fail(resp);
                            break;
                        // send_app_msg:confirm 发送成功
                        case 'send_app_msg:confirm':
                        case 'send_app_msg:ok':
                            callbacks.confirm && callbacks.confirm(resp);
                            break;
                    }
                    // 无论成功失败都会执行的回调
                    callbacks.all && callbacks.all(resp);
                });
            };
            WeixinJSBridge.on('menu:share:appmessage', function (argv) {
                if (callbacks.async && callbacks.ready) {
                    if(!callbacks.__dataLoadedFuncInited) {
                        var loadedCb = callbacks.dataLoaded || new Function();
                        callbacks.dataLoaded = function (newData) {
                            loadedCb(newData);
                            sendAppMessage(newData);
                        };
                        callbacks.__dataLoadedFuncInited = true;
                    }
                    // 然后就绪
                    callbacks.ready && callbacks.ready(argv);
                } else {
                    // 就绪状态
                    callbacks.ready && callbacks.ready(argv);
                    sendAppMessage(data);
                }
            });
        }
    
        /**
         * 分享到腾讯微博
         * @param       {Object}    data       待分享的信息
         * @p-config    {String}    imageUrl   图片地址
         * @p-config    {String}    link       链接地址
         * @p-config    {String}    desc       描述
         * @p-config    {String}    title      分享的标题
         *
         * @param       {Object}    callbacks  相关回调方法
         * @p-config    {Boolean}   async                   ready方法是否需要异步执行,默认false
         * @p-config    {Function}  ready(argv)             就绪状态
         * @p-config    {Function}  dataLoaded(data)        数据加载完成后调用,async为true时有用,也可以为空
         * @p-config    {Function}  cancel(resp)    取消
         * @p-config    {Function}  fail(resp)      失败
         * @p-config    {Function}  confirm(resp)   成功
         * @p-config    {Function}  all(resp)       无论成功失败都会执行的回调
         */
        function weixinShareWeibo(data, callbacks) {
            callbacks = callbacks || {};
            var shareWeibo = function (theData) {
                WeixinJSBridge.invoke('shareWeibo', {
                    "content":theData.desc,
                    "link":theData.link,
                    "img_url":theData.imgUrl,
                    "title":theData.title,
                    "img_width":"120",
                    "img_height":"120"
                }, function (resp) {
                    switch (resp.err_msg) {
                        // share_weibo:cancel 用户取消
                        case 'share_weibo:cancel':
                            callbacks.cancel && callbacks.cancel(resp);
                            break;
                        // share_weibo:fail 发送失败
                        case 'share_weibo:fail':
                            callbacks.fail && callbacks.fail(resp);
                            break;
                        // share_weibo:confirm 发送成功
                        case 'share_weibo:confirm':
                        case 'share_weibo:ok':
                            callbacks.confirm && callbacks.confirm(resp);
                            break;
                    }
                    // 无论成功失败都会执行的回调
                    callbacks.all && callbacks.all(resp);
                });
            };
            WeixinJSBridge.on('menu:share:weibo', function (argv) {
                if (callbacks.async && callbacks.ready) {
                    if(!callbacks.__dataLoadedFuncInited) {
                        var loadedCb = callbacks.dataLoaded || new Function();
                        callbacks.dataLoaded = function (newData) {
                            loadedCb(newData);
                            shareWeibo(newData);
                        };
                        callbacks.__dataLoadedFuncInited = true;
                    }
                    // 然后就绪
                    callbacks.ready && callbacks.ready(argv);
                } else {
                    // 就绪状态
                    callbacks.ready && callbacks.ready(argv);
                    shareWeibo(data);
                }
            });
        }
    
        /**
         * 调起微信Native的图片播放组件。
         * 这里必须对参数进行强检测,如果参数不合法,直接会导致微信客户端crash
         * 
         * @param {String} curSrc 当前播放的图片地址
         * @param {Array} srcList 图片地址列表
         */
        function imagePreview(curSrc,srcList) {
            if(!curSrc || !srcList || srcList.length == 0) {
                return;
            }
            WeixinJSBridge.invoke('imagePreview', {
                'current' : curSrc,
                'urls' : srcList
            });
        }
    
        /**
         * 显示网页右上角的按钮
         */
        function showOptionMenu() {
            WeixinJSBridge.call('showOptionMenu');
        }
    
        /**
         * 隐藏网页右上角的按钮
         */
        function hideOptionMenu() {
            WeixinJSBridge.call('hideOptionMenu');
        }
    
        /**
         * 显示底部工具栏
         */
        function showToolbar() {
            WeixinJSBridge.call('showToolbar');
        }
    
        /**
         * 隐藏底部工具栏
         */
        function hideToolbar() {
            WeixinJSBridge.call('hideToolbar');
        }
    
        /**
         * 返回如下几种类型:
         *
         * network_type:wifi     wifi网络
         * network_type:edge     非wifi,包含3G/2G
         * network_type:fail     网络断开连接
         * network_type:wwan     2g或者3g
         *
         * 使用方法:
         * WeixinApi.getNetworkType(function(networkType){
         *
         * });
         *
         * @param callback
         */
        function getNetworkType(callback) {
            if (callback && typeof callback == 'function') {
                WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
                    // 在这里拿到e.err_msg,这里面就包含了所有的网络类型
                    callback(e.err_msg);
                });
            }
        }
    
        /**
         * 当页面加载完毕后执行,使用方法:
         * WeixinApi.ready(function(Api){
         *     // 从这里只用Api即是WeixinApi
         * });
         * @param readyCallback
         */
        function wxJsBridgeReady(readyCallback) {
            if (readyCallback && typeof readyCallback == 'function') {
                var Api = this;
                var wxReadyFunc = function () {
                    readyCallback(Api);
                };
                if (typeof window.WeixinJSBridge == "undefined"){
                    if (document.addEventListener) {
                        document.addEventListener('WeixinJSBridgeReady', wxReadyFunc, false);
                    } else if (document.attachEvent) {
                        document.attachEvent('WeixinJSBridgeReady', wxReadyFunc);
                        document.attachEvent('onWeixinJSBridgeReady', wxReadyFunc);
                    }
                }else{
                    wxReadyFunc();
                }
            }
        }
    
        return {
            version         :"1.4",
            ready           :wxJsBridgeReady,
            shareToTimeline :weixinShareTimeline,
            shareToWeibo    :weixinShareWeibo,
            shareToFriend   :weixinSendAppMessage,
            showOptionMenu  :showOptionMenu,
            hideOptionMenu  :hideOptionMenu,
            showToolbar     :showToolbar,
            hideToolbar     :hideToolbar,
            getNetworkType  :getNetworkType,
            imagePreview    :imagePreview
        };
    })();

    转自:https://github.com/zxlie/WeixinApi/blob/master/WeixinApi.js

  • jQuery的deferred对象详解 转载

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本。

  • load some plain JavaScript files that do not define modules

    require(["some/script.js"], function() {
        //This function is called after some/script.js has loaded.
    });

    截取自:http://www.requirejs.org/docs/why.html

  • 加载非规范的模块

    官方示例:

    http://www.requirejs.org/jqueryui-amd/example/webapp/app.html

    /**
      * Ask for 'require', 'jquery' and 'jqueryui/tabs' as dependencies.
      *
      * 'require' is asked for as best practice, since it used inside the
      * require callback to dynamically load the datepicker. Since 'require'
      * is a module (provided by RequireJS), it is passed as the first argument
      * to the require callback. "req" is used as the function argument name
      * so the RequireJS optimizer will not pick up the dynamic load of
      * the 'jqueryui/datepicker', 'jqueryui/datepicker-fr' modules and
      * include them in the optimized build for main.js (see app.build.js
      * for more information on the optimized main.js build profile.)
      *
      * The require-jquery.js file registers jQuery as a module,
      * so this require callback will receive it as the second function
      * argument, since 'jquery' is the second dependency in the
      * dependency array.
      *
      * 'jquery/ui/tabs' does not export a module
      * value (it just augments jQuery), so it will not have a value for it
      * passed to the require callback. No need to assign a function argument
      * for it.
      */
    require({
        //Set config for finding 'jqueryui'. The path is relative
        //to the location of require-jquery.js.
        paths: {
            jqueryui: 'jqueryui-1.8.13/jqueryui'
        }
    }, ['require', 'jquery', 'jqueryui/tabs'], function (req, $) {
    
        //Wait for dom ready before setting up widgets.
        $(function () {
    
            //Make the tabs.
            $('#tabs')
                .tabs({
                    load: function (event, ui) {
                        //If the second tab is clicked, dynamically load
                        //the datepicker.
                        if (ui.index === 1) {
                            //Load the datepicker in French, on demand.
                            req(['jqueryui/datepicker', 'jqueryui/datepicker-fr'],
                                function () {
                                    $('#datepicker').datepicker();
                                }
                            );
                        }
                    }
                })
                //Make the tabs visible now that the widget has been instantiated.
                .removeClass('invisible');
        });
    });

     

    网上帖子:

    理论上,require.js加载的模块,必须是按照AMD规范、用define()函数定义的模块。但是实际上,虽然已经有一部分流行的函数库(比如jQuery)符合AMD规范,更多的库并不符合。那么,require.js是否能够加载非规范的模块呢?

    回答是可以的。

    这样的模块在用require()加载之前,要先用require.config()方法,定义它们的一些特征。

    举例来说,underscore和backbone这两个库,都没有采用AMD规范编写。如果要加载它们的话,必须先定义它们的特征。

    require.config({     shim: {       ‘underscore’:{         exports: ‘_’       },       ‘backbone’: {         deps: [‘underscore’, ‘jquery’],         exports: ‘Backbone’       }     }   });

     

     

    require.config()接受一个配置对象,这个对象除了有前面说过的paths属性之外,还有一个shim属性,专门用来配置不兼容的模块。具体来说,每个模块要定义(1)exports值(输出的变量名),表明这个模块外部调用时的名称;(2)deps数组,表明该模块的依赖性。

    比如,jQuery的插件可以这样定义:

    shim: {
        'jquery.scroll': {
          deps: ['jquery'],
          exports: 'jQuery.fn.scroll'
        }
      }

    转自:http://www.ruanyifeng.com/blog/2012/11/require_js.html

  • help main site learn.knockoutjs.com

    http://learn.knockoutjs.com/#/?tutorial=intro 直接在线学习

    <!– This is a view – HTML markup that defines the appearance of your UI –> <p>First name: <strong data-bind="text: firstName"></strong></p> <p>Last name: <strong data-bind="text: lastName"></strong></p> <p>Full name: <strong data-bind="text: fullName"></strong></p> <p>First name: <input data-bind="value: firstName"/></p> <p>Last name: <input data-bind="value: lastName"/></p>

    // This is a simple viewmodel – JavaScript that defines the data and behavior of your UI function AppViewModel() { this.firstName = ko.observable("Bert"); this.lastName = ko.observable("Bertington2121"); this.fullName = ko.computed(function(){ return this.firstName()+" "+ this.lastName(); },this); } // Activates knockout.js ko.applyBindings(new AppViewModel());

    knockoutjs 练习界面:

    image

  • 流行技术

    客户端技术: http://jquery.com/           html对象操作 http://knockoutjs.com/                 数据绑定 https://github.com/ericmbarnard/Knockout-Validation                    数据验证 http://knockoutjs.com/documentation/plugins-mapping.html        将服务端的json数据映射到客户端knockout对象 http://www.requirejs.org/            模块化加载器,按需加载,模块化管理脚本 http://www.json.org/js.html                       低版本IE json 的补丁 http://millermedeiros.github.io/crossroads.js/  客户端url解析管理 https://github.com/millermedeiros/hasher            客户端url hash管理,hasher依赖这个库http://millermedeiros.github.io/js-signals/ https://github.com/federico-lox/pubsub.js             javascript消息通讯管理,利用这个来实现模块间通讯 框架方面可以参考这个:http://durandaljs.com/  crossroad,hasher,signals,pubsub等脚本 服务端技术: http://www.asp.net/web-api                      webapi