Home - lvsheng/travel-zepto GitHub Wiki

仅对自己学习zepto源码过程中浅薄的想法作一些记录

zepto的目标是面向现代浏览器提供一套类jquery接口的轻量库。

感觉这类库的意义很大一部分应该是简化了浏览器查找dom元素、并进一步对查找到的元素进行一些操作(改变样式、html、增加动画等)提供更简便的接口(而不是自己遍历每一个元素,调用浏览器更面向实现而非使用的接口对其进行操作); 以及提供一些dom之外的简便接口(语言增强、非dom接口简化。如ajax、inArray等)。

最初期的zepto也只提供了选择dom、html、css、anim、prepend/append/before/after、事件绑定以及ajax这些功能。

$方法与dom的包装

(接上节)所以核心在$方法上。

这个方法根据选择器选择到对应元素并返回包装后的结果对象(结果中可以取到各直接dom对象,并且附带了一批操作这些dom的方法)。

  1. zepto最一开始(initial commit中)是把操作dom的扩展函数直接放到$上,并且在$方法里将这些方法与选择到的dom对象拼为一个包装后对象返回。
  2. 之后(第二天于首次代码调整的commit中)直接把选择到的dom放在了$的dom属性上,在$方法里返回自身($)。
    • 这样$自身既是一个全局的被选择dom的包装容器,同时也是选择dom的方法。想扩展对dom的操作也可以很方便直接增加方法来实现。
    • 虽然最终应该一定会改为原型方式的多例,但初始阶段直接这样暴力解决也没有太大问题。用作者自己的话说,"simplify more"。
  3. 再之后(commit),在$方法里根据参数是string还是function来复用了自己的双重身份:
    1. dom选择与遍历操作dom的模板
    2. 将dom扩展函数中重复的被选择元素遍历与为达到链式调用而做的返回值部分抽到了$中。 即便让一个函数有了双重身份,作者也并没有教条地进行再次的过度设计,而是使用最简单简便最少代码的方式完成了功能,其实是更易读的。
  4. 增加了$.fn这个名字空间。虽然每一次被选择到的dom仍然全局保存到$上,但将对这些dom操作的扩展给到了一个独立的名字空间中。更明确。

再之后增加事件绑定功能时,其实就已经遇到了被选择到的dom在全局上唯一导致异步回调函数中不能拿到正确dom的问题。作者的临时解决方式是用闭包保存(选择器)。

然后后来将prepend,append,before,after这些扩展不再是直接写在$.fn上,而是根据其一致性用配置+一个方法循环生成这四个方法。(即扩展dom操作函数已经不只是在.fn上直接写,也可能批量、动态为其赋值)。

逐步完善、快速迭代、不完全原型作为结构尝试,细节后续再优化

而非一次就将一个小功能点做到底做完整做到最优最普适考虑了各种情况。

典型如对dom包装对象的位置($(return {}) -> $ -> $.fn -> children of $.fn)、ajax方法(目前为止甚至还因为没考虑清如何保持简单而没有增加post发data的能力)、只有html没有text、css接口很原始(需要直接写style字符串)等

关于代码风格

  • 更注重代码简洁而非各种约束。
    • 完全不会说一定要按面向对象来写,要用原型链,要怎么怎么样。而是就按着让代码简洁(对应也应该是更易读吧),然后对会影响下一步扩展的地方再做必要的调整使其更易扩展。
    • 如多变量声明使用逗号分隔而非多行var(不过感觉很多时候这样不好),简单if、循环、function使用单行等。
  • 习惯写缩写(不过还是感觉只应写很容易理解很约定俗成的缩写)。

关于单元测试

  • 有单元测试。
  • 根据页面中元素的内容、属性等进行测试

动画的实现

先transition再transform