您的位置:首页 > Web前端 > JQuery

迷你版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.html

animate

/article/4682276.html

结语

我们今天对zepto做了一个整理性学习,希望对各位有帮助,最后微博求粉!!!
http://weibo.com/yiquinian/home?wvr=5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: