<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Your awesome title</title>
    <description>Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.</description>
    <link>http://surunzi.github.io/KissyLearning/</link>
    <atom:link href="http://surunzi.github.io/KissyLearning/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Kissy动画对比jQuery动画的五个亮点</title>
        <description>&lt;p&gt;Kissy动画模块的使用方法基本上与jQuery动画相差不了多少。除了提供jQuery动画所具有的功能外，Kissy在此之上又添加了不少有用的特性。假如你觉得jQuery动画满足不了你的需求，不妨试下Kissy的Anim模块。&lt;/p&gt;

&lt;h3 id=&quot;css-transform&quot;&gt;1.支持跨浏览器的css transform&lt;/h3&gt;

&lt;p&gt;CSS3中的transform可以让我们很容易地对元素进行平移、旋转、缩放等操作，然而浏览器前缀给我们的使用增加了诸多不便。在没有使用CSS预处理的情况下，每次@keyframes都必须写上几份着实让人感到厌烦。而且利用@keyframes控制动画在某些情况下也并不是那么合适。Kissy的Anim模块支持跨浏览器的css transform，不仅使用起来就跟其它属性变换一样简单，同时还能够使用CSS3的transition来提高动画性能。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;new Anim('#object', {
    'left': 555,
    'transform': 'rotate(360deg)'
}, 0.5).run();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;点击&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/animDemo/&quot;&gt;这里&lt;/a&gt;查看transform示例。&lt;/p&gt;

&lt;h3 id=&quot;section&quot;&gt;2.暂停恢复动画&lt;/h3&gt;

&lt;p&gt;Kissy可以在动画过程中随时暂停并重新开始动画。假如你是在开发一个具有多种动画效果的复杂Web应用，这个功能将会派上很大的用场。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Node.one('#run').on('click', function () {
    anim = new Anim('#object', {
            'left': 555,
            'transform': 'rotate(360deg)'
    }, 5);
    anim.run();
});
Node.one('#stop').on('click', function () {
    anim.stop();
});
Node.one('#pause').on('click', function () {
    anim.pause();
});
Node.one('#resume').on('click', function () {
    anim.resume();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;点击&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/animDemo/control.html&quot;&gt;这里&lt;/a&gt;查看控制示例。&lt;/p&gt;

&lt;h3 id=&quot;easing&quot;&gt;3.内置多种easing效果&lt;/h3&gt;

&lt;p&gt;jQuery需要额外的插件才能够支持多种效果，而Anim模块本身就自带了多种效果，可取值：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;swing | easeNone | linear | easeIn | easeOut 
easeBoth | easeInStrong | easeOutStrong | easeBothStrong 
elasticIn | elasticOut | elasticBoth | backIn
backOut | backBoth | bounceIn | bounceOut
bounceBoth | cubic-bezier(p1x, p1y, p2x, p2y)（所有取值必须在[0,1]之间）
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;点击&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/animDemo/easing.html&quot;&gt;这里&lt;/a&gt;查看各种平滑函数的实际使用效果。&lt;/p&gt;

&lt;h3 id=&quot;section-1&quot;&gt;4.自定义动画机制&lt;/h3&gt;

&lt;p&gt;什么是自定义动画呢？简单来说，就是你可以自行定义每个属性各自的变化效果，而不必全部都采用同一套方式。利用这个特性，你可以更加自由地控制动画的效果，比如下面这个，让透明度在0和1中进行改变，从而实现一闪一闪的效果：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;new Anim('#object', {
    'opacity': {
        frame: function (anim, fx) {
            var dom = anim.node,
                opacity = dom.style.opacity;
            if (opacity === '1') {
                dom.style.opacity = 0;
            } else {
                dom.style.opacity = 1;
            }
        }
    },
    'left': {
        value: 555,
        easing: 'swing'
    },
    'transform': {
        value: 'scale(0.01)',
        easing: 'elasticBoth'
    }
}, 5).run();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;点击&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/animDemo/custom.html&quot;&gt;这里&lt;/a&gt;查看自定义动画的效果。&lt;/p&gt;

&lt;h3 id=&quot;section-2&quot;&gt;5.对普通对象使用动画函数&lt;/h3&gt;

&lt;p&gt;Anim模块也可以作用在普通对象之上，具体怎样就不多说了，请点击&lt;a href=&quot;http://docs.kissyui.com/1.4/docs/html/demo/anim/demo7.html&quot;&gt;此处&lt;/a&gt;查看官网的例子。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var o = {r: 1};
var anim = new Anim(o, {
    r: 100
}, {
    easing: &quot;swing&quot;,
    duration: 1,
    frame: function (anim, fx) {
        circle(100, 100, fx.val);
    }
});
anim.run();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;发挥自己的想像力，多试一下不同的组合，合理的利用Anim模块就可以创造出让人惊叹的动画效果来！戳&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/anim/&quot;&gt;此处&lt;/a&gt;可查看Anim模块的使用范例，仅供参考^_^ &lt;/p&gt;
</description>
        <pubDate>Fri, 20 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/20/key-difference-between-jquery-animate-and-kissy-anim/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/20/key-difference-between-jquery-animate-and-kissy-anim/</guid>
      </item>
    
      <item>
        <title>Base模块的扩展与插件机制</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;本次的例子是一个极为简单的wysiwyg编辑器，演示地址和源码分别戳&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/plugin/&quot;&gt;此处&lt;/a&gt;和&lt;a href=&quot;https://github.com/surunzi/KissyLearning/tree/master/example/plugin/&quot;&gt;此处&lt;/a&gt;^_^&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Base模块除了可以实现类的继承，本身还具有扩展和插件机制以便更好进行代码复用和类结构管理。先来看一下什么是扩展：&lt;strong&gt;Base.extend([类数组], {}, {})&lt;/strong&gt;。向extend方法第一个参数传入一个类数组，该数组中的类所具有的方法将会被添加入新建的类中。出现同名方法的话，扩展类数组中靠后的优先，覆盖前面的，主类的最优先，比如下面的例子：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var A = Base.extend({
    constructor: function () {},
    run: function () {
        console.log('a');
    }
});
var B = Base.extend({
    constructor: function () {},
    run: function () {
        console.log('b');
    }
});
var C = Base.extend([A, B], {
});
var c = new C;
c.run();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;B在A之后，所以结果应该是’b’，再如下面：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var A = Base.extend({
    constructor: function () {},
    run: function () {
        console.log('a');
    }
});
var B = Base.extend({
    constructor: function () {},
    run: function () {
        console.log('b');
    }
});
var C = Base.extend([A, B], {
    run: function () {
        console.log('c');
    }
});
var c = new C;
c.run();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;主类中出现了run方法，覆盖掉B中的run方法，结果是c。通过Base扩展的机制可以实现类似于多继承的效果，Kissy内部很多组件也是通过此方法创建的，比如overlay：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Container.extend([
    ContentBox,
    Shim,
    Loading,
    AlignExtension,
    Mask,
    OverlayEffect
], {...}, {...});
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;注：扩展类数组中的构造方法比如上例中的A和B，如果是通过Base.extend方法创建的，需要覆盖掉原有的constructor方法。因为在默认constuctor方法链上有操作会出现循环调用进而导致堆栈溢出，具体是哪个语句导致在这里就不细讲了，有兴趣的可以自行看一下base模块和attribute模块的源码。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;除了扩展机制外，Base模块还提供了Plugin机制在类的实例（而不是类本身）上动态添加特性。Base提供了一个配置（plugins）和三个函数（plug、unplug和getPlugin）用来管理插件。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;editor.plug(undo);
editor.plug(redo);
editor.plug(bold);
editor.plug(italic);
editor.unplug(bold);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;plug方法做的实际上只是将传入的对象赋值到实例的plugins属性中去，同时调用对象的pluginInitializer方法。如果传入参数为function类型则会先将其实例化。unplug做的则是相反的工作，调用plugins中指定的plugin的pluginDestructor方法，并将其从plugins数组中去除。getPlugin不用说，当然是返回指定的plugin。&lt;/p&gt;

&lt;p&gt;具体如何使用扩展和插件机制请参考本次的&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/plugin/&quot;&gt;简单wygiwys编辑器&lt;/a&gt;例子。当然，可能这并非是使用它们的最佳情景。具体什么时候该使用它们还是要由你自己依据实际的使用情况来决定。&lt;/p&gt;
</description>
        <pubDate>Sat, 14 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/14/plugin-design-pattern-of-base-module/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/14/plugin-design-pattern-of-base-module/</guid>
      </item>
    
      <item>
        <title>Base类继承中的callSuper实现</title>
        <description>&lt;p&gt;刚接触到Kissy的Base模块时就很好奇它的callSuper方法到底是怎样实现的，这东西实在是太方便了。首先简述一下callSuper的作用：假设现在对象o有方法a，在方法a内调用callSuper。callSuper将找到o的原型op，并调用op中的方法a。&lt;/p&gt;

&lt;p&gt;可惜，在callSuper里面能够访问到的只有调用该方法a的对象和调用callSuper的方法。调用方法a的对象不一定是o，因为有可能o其实是该对象的原型链上的一个原型。那么，该怎么做呢？&lt;/p&gt;

&lt;p&gt;attribute/src/attribute.js:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;callSuper: function () {
        var method, obj,
            self = this,
            args = arguments;
        // 如果调用callSuper的对象本身就是function
        if (typeof self === 'function' &amp;amp;&amp;amp; self.__name__) {
            method = self;
            obj = args[0];
            args = Array.prototype.slice.call(args, 1);
        } else {
            method = arguments.callee.caller;
            if (method.__wrapped__) {
                method = method.caller;
            }
            obj = self;
        }
        var name = method.__name__;
        if (!name) {
            return undefined;
        }
        var member = method.__owner__.superclass[name];
        if (!member) {
            return undefined;
        }
        return member.apply(obj, args || []);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;从callSuper的源代码可以知道，callSuper首先获取到调用它的函数method和其函数名name。然后再通过method.__owner__获取到其所在的类构造方法，之后在通过该类构造方法的superclass得到method所在对象的原型，最后再调用原型中的同名方法。当然，方法中的__name__和__owner__等属性都是在用extend方法创建类时就添加上去的。&lt;/p&gt;

&lt;p&gt;PS：本站停更。考完分布式计算还有嵌入式课程设计答完辩后再回来继续更=_=&lt;/p&gt;
</description>
        <pubDate>Thu, 12 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/learning-notes/2014/06/12/things-behind-call-super/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/learning-notes/2014/06/12/things-behind-call-super/</guid>
      </item>
    
      <item>
        <title>Kissy快速入门</title>
        <description>&lt;h3 id=&quot;section&quot;&gt;什么是模块化？&lt;/h3&gt;

&lt;p&gt;Kissy使用模块化开发，简单来说，就是将Kissy划分成多个部分，每个部分包含若干相关联的功能。在开发过程中，需要用到哪一部分功能就需要载入相应的模块。需要进行DOM操作，就载入dom或者node模块；需要进行ajax操作，就载入io模块；需要进行cookie操作，就载入cookie模块，依此类推。&lt;/p&gt;

&lt;h3 id=&quot;kissy&quot;&gt;载入Kissy库&lt;/h3&gt;

&lt;p&gt;在使用Kissy库之前，必须将Kissy引入到你的页面中去，只需要在HTML页面中插入以下代码即可：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;http://g.tbcdn.cn/kissy/k/1.4.3/seed.js&quot; data-config=&quot;{combine:true}&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;seed.js文件只是一个模块加载器，并没有包含所有的Kissy文件。当你需要用到某些模块时，该加载器会动态加载所需要的文件。因此，如果是本地调试，不能单独将seed.js文件下载下来，必须下载整个Kissy库，当前最新的1.4.3版可戳&lt;a href=&quot;https://github.com/kissyteam/kissy/archive/v1.4.3.zip&quot;&gt;此处&lt;/a&gt;下载。&lt;/p&gt;

&lt;h3 id=&quot;kissyuse&quot;&gt;Kissy.use&lt;/h3&gt;

&lt;p&gt;在Kissy中加载各模块使用use方法，该方法挂载在Kissy对象上：&lt;strong&gt;KISSY.use(name,sandbox)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;其中name为数组，指明需要使用的模块，sandbox为匿名函数，第一个参数为S，传入KISSY全局对象，其他参数依次带入所载入的模块返回的对象。&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.use(['node', 'io'], function (S, Node, io) {
    var ele = Node.one('#ele');
    ...
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;section-1&quot;&gt;学习资料&lt;/h3&gt;

&lt;p&gt;进一步学习可前往：&lt;a href=&quot;http://surunzi.github.io/KissyLearning/tutorial/&quot;&gt;教程&lt;/a&gt;、&lt;a href=&quot;http://docs.kissyui.com/&quot;&gt;官网&lt;/a&gt;、&lt;a href=&quot;http://surunzi.github.io/KissyLearning/document/&quot;&gt;文档&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;如果有好的关于Kissy的学习资料，请发送邮件给我：&lt;strong&gt;surunzi1992@gmail.com&lt;/strong&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 12 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/12/quick-start/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/12/quick-start/</guid>
      </item>
    
      <item>
        <title>使用requirejs的define方法来添加模块</title>
        <description>&lt;p&gt;记得之前在Kissy的官网上，有人建议将依赖模块的声明放到前面去，这样看起来会比较方便些。官网提供的解决方法是：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.add(function(S, require){
    var A = require('a');
    var B = require('b');
    var C = require('c');
    // Your code...
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;如果觉得对这种解决方法不满意的话，我们也可以自行解决，方法就是在KISSY.add方法上再套上一层将参数位置颠倒，比如下面：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(function (S) {
    window.define = S.define = function (deps, callback) {
        var slice = Array.prototype.slice;
            
        if (arguments.length === 1) {
            S.add(deps);
            return;
        }
        
        S.add(function () {
            return callback.apply(null, slice.apply(arguments, [1]));
        }, {
            requires: deps
        });
    }
})(KISSY);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将这段代码紧贴在Kissy库后面，就可以用requireJs的方法来添加模块了，比如下面：&lt;/p&gt;

&lt;p&gt;module-A.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;define(['node', 'base'], function (Node, Base) {
    ...
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;或者是下面这样：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;define(function () {
    ...
})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;当然这段代码很粗糙，并没有做太多处理，你可以根据自己的实际需要再对其进行定制修改。。&lt;/p&gt;
</description>
        <pubDate>Mon, 09 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/09/use-requirejs-style-to-add-module/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/09/use-requirejs-style-to-add-module/</guid>
      </item>
    
      <item>
        <title>使用Base模块实现类的创建和继承</title>
        <description>&lt;p&gt;大型JavaScript应用程序除了需要将程序进行拆分模块化之外，通常也是免不了要使用&lt;strong&gt;类&lt;/strong&gt;这种在其它多数编程语言中极为常用的结构体，这其中要以Java，C#最为典型。JavaScript中并没有真正的类，但我们仍可以通过构造函数和new运算符来模拟出传统的类，并利用它来更好地组织代码结构，提高其可维护性。&lt;/p&gt;

&lt;p&gt;假设我们现在要实现一个Circle类，它继承于Geometry类。在不借助任何外部库的时候，最常见的写法通常是这样的：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Geometry(x, y) {
    this.x = x;
    this.y = y;
    ...
}
Geometry.prototype.render = function () {
    ...
}
function Circle(x, y, r) {
    Geometry.apply(this, [x, y]);
    this.r = r;
}
Circle.prototype = new Geometry();
Circle.prototype.getRadius = function () {
    ...
}
var c = new Circle(10, 10, 5);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;仔细看下，就会发觉这样子的写法其实存在着不少问题。其中最明显的一点就是不直观，试问下如果有一堆这样的代码，你能一眼就看出类与类之间的关系吗？为了让类的创建和继承更加简便化，不少类库都提供了不错的解决方案。以Kissy为例，我们可以使用Base模块很容易地来实现类的创建和继承。&lt;/p&gt;

&lt;p&gt;首先创建Geometry类：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var Geometry = Base.extend({
    // 在这里添加类的方法
    // 构造函数（可选）
    constructor: function (x, y) {
    ...
    },
    // 初始化函数，类创建后执行
    initializer: function () {
        ...
    },
    addStyle: function () {
        ...
    },
    render: function (canvas) {
        ...
    }
}, {
    // 这里是类名（可选）
    name: 'Geometry',
    // 类的属性，可使用默认的set和get方法，也可以自定义
    ATTRS: {
        // 在这里添加类的属性
        x: {
            value: 0,
            setter: function () {},
            getter: function () {}
        },
        y: {
            value: 0
        }
        ...
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;接下来创建Circle类继承Geometry类：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var Circle = Geometry.extend({
    // 可以直接覆盖父类中的同名函数
    addStyle: function () {
        // 使用callSuper访问父类中的方法
        this.callSuper();
        ...
    },
    render: function (canvas) {
        ...
    }
}, {
    name: 'Circle',
    ATTRS: {
        r: {
            value: 0
        }
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;总结一下创建类的步骤：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;如果不继承任何类，则调用Base.extend({方法}, {属性})创建类&lt;/li&gt;
  &lt;li&gt;如果是继承已有类，则调用类名.extend({方法}, {属性})创建类&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;以上就是Base模块实现类创建和继承的最基础的使用方法，更多详细信息请查看&lt;a href=&quot;http://docs.kissyui.com/1.4/docs/html/tutorials/kissy/base/index.html&quot;&gt;官方教程&lt;/a&gt;。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;完整的示例和源码请戳&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/class/&quot;&gt;此处&lt;/a&gt;和&lt;a href=&quot;https://github.com/surunzi/KissyLearning/tree/master/example/class/&quot;&gt;此处&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sun, 08 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/08/class-inheritance/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/08/class-inheritance/</guid>
      </item>
    
      <item>
        <title>Loader模块add方法源码一览</title>
        <description>&lt;p&gt;Kissy框架的模块加载器中最重要的就是add和use方法：add用于添加模块，use用于加载并使用模块。本文只介绍关于add方法的大概内部实现流程，use将在往后的学习笔记中介绍。&lt;/p&gt;

&lt;p&gt;稍微了解过Kissy的话都应该知道，Kissy使用use方法加载外部模块时将发起http请求模块所在的js文件，而模块文件内均有一个add方法。js文件加载完毕之后便会执行该add方法。那么，add方法究竟做了什么呢？&lt;/p&gt;

&lt;p&gt;loader/src/loader.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(function (S) {
    var Loader = S.Loader,
        ComboLoader = Loader.ComboLoader;
    Utils.mix(S, {
        add: function (name, factory, cfg) {
            ComboLoader.add(name, factory, cfg, arguments.length);
        }
    });
})(KISSY);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;将loader.js中必要的文件删除后，可以看到Kissy.add其实只是在ComboLoader.add之上做了一层封装。&lt;/p&gt;

&lt;p&gt;loader/src/combo-loader.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(function (S, undefined) {
    var Loader = S.Loader,
        addModule = Utils.addModule;
    ...
    function ComboLoader(callback) {
        ...
    }
    ...
    ComboLoader.add = function (name, factory, config, argsLen) {
        // KISSY.add('xx',[],function(){});
        if (argsLen === 3 &amp;amp;&amp;amp; Utils.isArray(factory)) {
            ...
        }
        // KISSY.add(function(){}), KISSY.add('a'), KISSY.add(function(){},{requires:[]})
        if (typeof name === 'function' || argsLen === 1) {
            ...
            addModule(name, factory, config);
        } else {
            ...
            addModule(name, factory, config);
        }
    };
    ...
    Loader.ComboLoader = ComboLoader;
})(KISSY);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ComboLoader.add主要是对传入的参数进行了一些顺序处理，以适应不同的参数传递，最终调用的是Utils.addModule。&lt;/p&gt;

&lt;p&gt;loader/src/utils.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(function (S) {
    var Loader = S.Loader,
        Env = S.Env,
        mods = Env.mods;
    ...
    mix(Utils, {
        ...
        createModule: function (name, cfg) {
            var module = mods[name];
            ...
            mods[name] = module = new Loader.Module(mix({
                name: name
            }, cfg));
            return module;
        },
        addModule: function (name, factory, config) {
            ...
            Utils.createModule(name, mix({
                name: name,
                status: Loader.Status.LOADED,
                factory: factory
            }, config));
        }
    });
})(KISSY);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Utils.addModule检测模块是否已被加载过后调用Utils.createModule。Utils.createModule最终创建Loader.Module实例并最终赋值到Kissy.Env.modes[name]中去。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Loader.Module构造函数在loader/src/data-structure.js中&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sat, 07 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/learning-notes/2014/06/07/inside-the-add-method-of-kissy-loader/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/learning-notes/2014/06/07/inside-the-add-method-of-kissy-loader/</guid>
      </item>
    
      <item>
        <title>Kissy模块加载器基础用法</title>
        <description>&lt;p&gt;Javascript模块化可以为我们带来代码复用、提高可维护性、按需加载文件等好处。目前比较流行的模块加载器有RequireJs和SeaJs。如果你正在使用Kissy库的话，就无需另外再去引入这些加载器，因为Kissy本身就是一个模块化的Javascript框架。本文将从一个实例出发说明Kissy模块化的基本使用方法，最终的效果可戳&lt;a href=&quot;http://surunzi.github.io/KissyLearning/example/module/&quot;&gt;此处&lt;/a&gt;进行查看。你也可以戳&lt;a href=&quot;https://github.com/surunzi/KissyLearning/tree/master/example/module/&quot;&gt;此处&lt;/a&gt;查看所有的源代码。&lt;/p&gt;

&lt;p&gt;首先建立HTML文件：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;...
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div id=&quot;title&quot;&amp;gt;
        &amp;lt;h1&amp;gt;模块按需加载&amp;lt;/h1&amp;gt;
        &amp;lt;span&amp;gt;请点击下面的按钮并同时查看网络请求情况&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id=&quot;btn-wrapper&quot;&amp;gt;
        &amp;lt;div id=&quot;btn&quot;&amp;gt;点我加载模块并执行&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;script src=&quot;http://g.tbcdn.cn/kissy/k/1.4.3/seed.js&quot; data-combine=&quot;{combine:true}&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;effect.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Kissy中添加模块的步骤如下：&lt;/p&gt;

&lt;p&gt;1.新建一个js文件，在其中添加如下的结构：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.add(function (S, Node) {
    /* 模块代码 */
    return;
    /* 最后可以返回结果供调用该模块的文件使用 */
}, {
    requires: ['node'] /* 可以加载多个该模块所依赖的模块，与函数的参数一一对应*/
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;比如我们这次例子的结构是以下这样的：&lt;/p&gt;

&lt;p&gt;snow.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.add(function (S, Node) {
    /* 变量定义 */
    var ...;
    // 初始化
    function init() {
    }
    // 开始执行动画
    function begin() {
    }
    // 绘制
    function draw() {
    }
    // 粒子构造函数
    function Particle() {
    }
    // 停止动画
    function stop() {
    }
    /* 将begin和stop方法返回供调用该模块的文件使用 */
    return {
        begin: begin,
        stop: stop
    };
}, {
    requires: ['node']
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;2.配置包&lt;/p&gt;

&lt;p&gt;由于我们使用的是淘宝CDN，如果不注册包的话发送文件请求是会以淘宝CDN的地址为前缀，所以必须注册包用来映射正确的URL地址。同时包也在指明请求合并中起作用，这里不属于本文讨论范围就不详谈了。&lt;/p&gt;

&lt;p&gt;以这次为例子:&lt;/p&gt;

&lt;p&gt;effect.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.config('packages', {
    'myModule': {
        base: window.location.href.replace('index.html', ''),
        ignorePackageNameInUri: true
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;其中base为包的url映射，可以把它当成单纯的字符串替换，例如：&lt;/p&gt;

&lt;p&gt;指明要使用’myModule/snow’这个包，它会将myModule替换为base, 请求地址为：base + ‘snow.js’；&lt;/p&gt;

&lt;p&gt;假如没有指定ignorePackageNameInUri为true，则请求地址为：base + ‘myModule/’ + ‘snow.js’。&lt;/p&gt;

&lt;p&gt;3.使用模块&lt;/p&gt;

&lt;p&gt;使用自定义模块就跟使用Kissy自带的模块一样简单，比如：&lt;/p&gt;

&lt;p&gt;effect.js&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.ready(function (S) {
KISSY.use('node', function (S, Node) {
    Node.one('#btn').on('click', function () {
        /* 点击按钮时加载snow模块并执行 */
        KISSY.use('myModule/snow', function (S, snow) {
            snow.begin();
        });
    });
});
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最后，总结一下创建自定义模块的步骤：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;新建文件，并用KISSY.add创建模块&lt;/li&gt;
  &lt;li&gt;如果有必要，注册模块所在包&lt;/li&gt;
  &lt;li&gt;用KISSY.use加载使用模块&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;更多关于Kissy Loader的信息请戳&lt;a href=&quot;http://docs.kissyui.com/1.4/docs/html/guideline/kmd.html&quot;&gt;这里&lt;/a&gt;和&lt;a href=&quot;http://docs.kissyui.com/1.4/docs/html/tutorials/kissy/loader/index.html&quot;&gt;这里&lt;/a&gt;^_^&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Fri, 06 Jun 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/06/basic-module-loader-usage/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/basic-tutorial/2014/06/06/basic-module-loader-usage/</guid>
      </item>
    
      <item>
        <title>jQuery用户快速上手Kissy</title>
        <description>&lt;h3 id=&quot;section&quot;&gt;1. 引入库文件&lt;/h3&gt;

&lt;p&gt;jQuery:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;jquery.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Kissy:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;http://g.tbcdn.cn/kissy/k/1.4.3/seed.js&quot; data-config=&quot;{combine:true}&quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Kissy跟jQuery一样，可以将其下载到本地进行使用，但更推荐使用淘宝的CDN。除能够减小服务器带宽压力，利用CDN加快js文件的载入速度外，还能直接使用combo，减少请求数，免去了让自己服务器支持combo功能的麻烦。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;section-1&quot;&gt;2. 开始使用&lt;/h3&gt;

&lt;p&gt;jQuery:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$(document).ready(function () {
    /* jQuery代码 */
});
// 或者
$(function () {
    /* jQuery代码 */ 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Kissy:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.use(['node'], function (S) {
S.ready(function (S) {
    var $ = S.all;
    /** jQuery风格代码 */
});
});
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;在Dom操作上面基本上可以当成jQuery来进行使用，但还存在些许不同，之后有时间会单独整理一篇文章列出其中的不同点，当然也可以先参考&lt;a href=&quot;http://cyj.me/jquery-kissy-rosetta/&quot;&gt;这篇文章&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;如果想要使用ajax功能的话，可以写成下面的形式：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.use(['node', 'io'], function (S) {
S.ready(function (S) {
    var $ = S.all,
        io = S.io,
        $.get = io.get,
        $.post = io.post;
    /** jQuery风格代码 */
});
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;最后说一点，本文只是用一种抖机灵的方式让使用jQuery的人能像用jQuery一样来使用Kissy，还是强烈建议去查看下Kissy的&lt;a href=&quot;http://docs.kissyui.com/1.4/docs/html/guideline/kmd.html&quot;&gt;模块化规范&lt;/a&gt;。毕竟，模块化才是Kissy相比于jQuery真正所具有的优势，至少在我看来是这样的。使用Kissy，你可以很方便地创建和管理自己的模块，得到类似使用requireJs管理模块依赖库所带来的好处，让开发过程变得更加简单高效，代码的可维护性更高。&lt;/p&gt;
</description>
        <pubDate>Fri, 30 May 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/basic-tutorial/2014/05/30/tutorial-for-jquery-user/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/basic-tutorial/2014/05/30/tutorial-for-jquery-user/</guid>
      </item>
    
      <item>
        <title>初窥Kissy源码结构</title>
        <description>&lt;p&gt;之前花了点时间大概看了下Kissy的官网部分文档，大致上也了解了Kissy的基本使用方法。当然，学东西的时候光看不练是很难真正将其掌握的。因此，也就有了这个放置在GitHub上的&lt;a href=&quot;https://github.com/surunzi/KissyLearning&quot;&gt;KissyLearning&lt;/a&gt;项目。考虑到网络上Kissy教程文档的缺乏，这里除了会发学习笔记外，可能还会发点傻瓜级教程什么的~_~&lt;/p&gt;

&lt;p&gt;点击&lt;a href=&quot;https://github.com/kissyteam/kissy&quot;&gt;此处&lt;/a&gt;查看Kissy项目的GitHub主页，其中src目录存放的就是Kissy的源码。从Build目录下可以打开seed.js（种子文件），可以看到包含了loader，features，ua三个基本模块。其中，loader（模块加载器）是Kissy的最开始部分。首先打开src/loader/目录下的build.xml文件，由最底部的代码得知，loader文件的合并顺序。&lt;/p&gt;

&lt;p&gt;Kissy/src/loader/build.xml：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;target name=&quot;concat&quot;&amp;gt;
    &amp;lt;concat destfile=&quot;${component.src.dir.tmp}/loader-pkg-debug.js&quot;
            encoding=&quot;${charset}&quot; outputencoding=&quot;${charset}&quot;&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/kissy.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/utils.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/data-structure.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/css-onload.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/get-script.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/configs.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/combo-loader.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/loader.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/i18n.js&quot;/&amp;gt;
        &amp;lt;path location=&quot;${component.src.dir}/init.js&quot;/&amp;gt;
    &amp;lt;/concat&amp;gt;
&amp;lt;/target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;首先来看kissy.js文件，把大部分代码删除掉，可以看到其基本结构下面这样子的：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var KISSY = (function (undefined) {
    var S;
    S = {
        /** Some code here. */
    };
    return S;
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;该文件定义一个KISSY的变量，作为整个库文件的最外层文件（命名空间），以免污染全局。其值是某自执行函数的返回值，即函数中所定义的S。该文件主要定义了全局命名空间，并定义了一小部分属性，诸如版本号，配置，日志等。&lt;/p&gt;

&lt;p&gt;接下来执行的是utils.js，data-structure.js…loader.js等文件，其基本结构大致如下：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(function (S) {
    /** Some code here. */
})(KISSY);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;利用自执行函数，将KISSY对象传入函数中，并将操作后需要保留的值或方法赋给S，即KISSY对象。&lt;/p&gt;

&lt;p&gt;在基本的加载器初始完成之后，便可以使用模块加载器来进行模块的添加和管理了，之后代码的基本结构如下：&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KISSY.add(function (S, require, exports, module) {
    /** Some code here. */
});
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;关于Kissy的模块定义规范可戳&lt;a href=&quot;http://docs.kissyui.com/1.4/docs/html/guideline/kmd.html&quot;&gt;此处&lt;/a&gt;查看。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;晚上大概扫了一下源码，就只了解了这么多，之后有空再细看。复习，不对。。是预习嵌入式去，祝自己下周考个好成绩。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;说笑的，求不挂就行(T＿T)&lt;/p&gt;
</description>
        <pubDate>Thu, 29 May 2014 00:00:00 +0800</pubDate>
        <link>http://surunzi.github.io/KissyLearning/learning-notes/2014/05/29/kissy-source-first-impression/</link>
        <guid isPermaLink="true">http://surunzi.github.io/KissyLearning/learning-notes/2014/05/29/kissy-source-first-impression/</guid>
      </item>
    
  </channel>
</rss>
