迷你版jQuery——zepto核心源码分析
2016-01-20 20:49
585 查看
前言
zepto号称迷你版jQuery,并且成为移动端dom操作库的首选事实上zepto很多时候只是借用了jQuery的名气,保持了与其基本一致的API,其内部实现早已面目全非!
艾伦分析了jQuery,小钗暂时没有那个本事分析jQuery,这里就恬不知耻说说自己对zepto的源码理解,希望对各位有用
首先zepto的出现其实还是很讨巧的,他看见了巨人jQuery在移动浪潮来临时的转身慢、牵挂多的问题
马上搞出了一套轻量级类jQuery框架代码,核心代码1000行不到,快速占领了移动端的市场,所以天下武学无坚不摧,为快不破啊!!!
也如艾伦所言,jQuery狭义的讲其实就是dom操作库
zepto将这点发扬光大,并且抛弃了浏览器兼容的包袱,甚至CSS3的前缀都不给加,这些因素造就了zepto小的事实,于是我们开始学习他吧
此文只是个人对zepto的粗浅理解,有误请提出
核心组成
zepto现在也采用了模块拆分,这样读起来其实代码十分清晰,门槛也低了很多,整个zepto核心模块保持在900行以内我们说他很好的发扬了dom库特点便是因为这900行基本在干dom操作的活
核心模块有以下部分组成:
① 闭包变量、工具类方法定义
这个部分主要为后面服务,比如说什么isFunction/isPlainObject/children其中有一个比较特别的变量是
zepto = {};
这个变量贯穿始终,也是zepto与jQuery很不一样的地方,jQuery是一个类,会创建一个个实例,而zepto本身就只是一个对象......
② zepto与jQuery的$
zepto第二阶段干的事情便是定义了一个类$ = function(selector, context){ return zepto.init(selector, context) }
而我们开始便说了zepto只是一个对象,而zepto.init也仅仅是返回了一个类数组的东西,于是我们这里便看到了zepto与jQuery的惊人差异
第一观感是zepto没有类操作!我们使用$('')的操作返回的也是zepto的实例
$对于zepto来说仅仅是一个方法,zepto却使用了非正规手法返回了实例......
View Code
创建元素
$方法的第二大功能便是创建元素了,比如我们这里的$("<p>Hello</p>");
这里依旧会经过zepto.init的处理,判断是否具有尖括号(<),有的话便会进入神奇的fragment逻辑创建文档碎片
dom = zepto.fragment(selector, RegExp.$1, context)
这里有一个正则表达式对传入的html进行解析,目标是标签名
PS:zepto对p标签的解析也会出问题,不建议使用
zepto.fragment = function(html, name, properties) {}
到fragment方法时,会传入html和那么并且会有相关属性,但是我们一般不这样干,仅仅希望创建DOM
View Code
里面的逻辑各位自己去看,我这里不多说了,还是很简单的,大概的想法是
创建一个空的div元素,将字符串装载,然后遍历div的子元素,最后返回一个node的集合数组,这个也就是我们实际需要的......
这个样子,创建标签或者selector选择器得到的结果是一致的
其它逻辑大同小异,我们直接就过了,zepto核心入口逻辑就到此结束了......
fn的实现
fn中包含了zepto的很多功能,要一一说明就多了去了,首先由$扩展开始说除了原型扩展外还为$包含了很多静态方法,比如什么uuid,isFunction,然后就开始了原型链扩展之路
$.fn与zepto.Z.prototype指向的是同一空间,这里达到了是扩展原型链的效果
View Code
这里的event可以是以空格分隔的字符串,一般情况下是单一的事件
event => 'mousedown touchstart' event => 'click'
然后这里开始了处理逻辑:
① 参数处理
第一步当然是做参数处理,会修正参数,比如你没有传事件句柄,这里会给个默认的,然后开始循环绑定,因为我们使用$()返回的是一个数组
进入循环逻辑后,this与element便是真资格的dom元素了,未经雕琢,开始是对one的处理,我们不予关注,继续向下便进入第一个关键点
简单情况下我们的selector为undefined,所以这里错过了一个事件委托的重要逻辑,我们先不予理睬,再往下便进入了闭包方法add了
这个情况下selector与delegator为undefined,仅仅是前3个参数有效
View Code
第一段代码就很重要:
var id = zid(element) function zid(element) { return element._zid || (element._zid = _zid++) }
这里的zid非常关键,这里的element为与原生对象,这里在上面加了一个_zid的属性,这个属性会跟随其由始至终,不会丢失,如果是zepto封装的dom对象的话,就很容易丢失,因为每次根据$()创建的dom都是新的,这个_zid放到原生属性上是很有意义的
第二个变量也很关键:
set = (handlers[id] || (handlers[id] = []))
我们所有绑定的事件以_zid为键值放在了外部闭包环境handlers对象中,每一个id对应的为一个数组,这个与绑定先后顺序相关
然后进入具体绑定逻辑:
完了这里会考虑是'mousedwon touchstart'的情况所以会有一个循环,我们这里由于只是click便不予理睬了,ready事件我们也直接忽略,进入逻辑后关键点来了
这里定义了一个handler对象,这个对象会存于handlers里面
View Code
触发事件时他这里首先会对事件参数event做一次封装返回,首先将三大事件对象进行新增接口
View Code
代码比较简单,可以直接进入remove的逻辑
View Code
其它
累了,略......Ajax
/article/4683132.htmlanimate
/article/4682276.html结语
我们今天对zepto做了一个整理性学习,希望对各位有帮助,最后微博求粉!!!http://weibo.com/yiquinian/home?wvr=5
相关文章推荐
- 在jQuery,如何判断页面元素是否存在?
- 开源JQuery框架 : Prime UI !
- jQuery核心
- jQuery Form 表单提交插件-----ajaxSubmit() 的应用
- 一个非常简单的jQuery分页插件
- jquery动态改变图片
- jQuery高性能自定义滚动条美化插件
- jquery.ajax error调试
- 新建WebService供JQuery调用及用js判断是否要调用服务器的submit
- jquery的$().each,$.each的区别
- php jquery 头像裁剪插件 croppic
- Jquery ajax 用户信息修改
- 写出高性能的JQuery
- JS,Jquery获取各种屏幕的宽度和高度
- jQuery获取事件元素
- Jquery中巧用Ajax的beforeSend方法
- jquery学习网站
- jquery.extend
- jquery跳出each循环
- jquery选择器