Zepto.js之一步步看源码(一)
程序员文章站
2024-03-24 13:33:34
...
最近博主再看zepto.js的源码,zepto.js相较起来比较简短,适合第一次读源码,主要是怕以后忘记,就写下笔记来记录这次源码之旅,总体来说收获还是挺大的。zepto.js就类似于一个迷你的jquery,直接来就仔细来看看这源码怎么回事,我用的版本是Zepto v1.1.6
首先我们看下总体结构
var Zepto = (function() {
return $
})()
window.Zepto = Zepto
window.$ === undefined && (window.$ = Zepto)
这里是一个自执行函数的返回值赋值给了Zepto,在下面给window下面的Zepto赋值,我们就可以通过Zepto(“#id”)这样来调用,之后的也是赋值给了window下的$,这也是我们最常见的$("#id")
,这个表达式是如何计算的呢,当前面是真的时候就返回后面的语句,如果不明白建议看看&&
的用法。
我们已经知道总体是怎么回事,那么我们就看看自执行函数里面返回的$是什么
$ = function(selector, context){
return zepto.init(selector, context)
}
这里可以看出这个$返回了一个初始化函数,这个初始化函数主要的左右是来判断$("")
这里面到底是什么样式,根据不同的样式来分配给不同的方法处理
zepto.init = function(selector, context) {
var dom
//如果是空的话就返回,一会再看zepto.Z()这个函数,其实就是绑定了原型链。
if (!selector) return zepto.Z()
else if (typeof selector == 'string') {
//两种情况$("<p></p>")和$("#id")
selector = selector.trim()
// fragmentRE = /^\s*<(\w+|!)[^>]*>/,下面这个就是第一种创建元素的情况
//这个正则表达式的意思是开头匹配(0,)个回车空格等符号下一个字符是<的之后有有{1,}个字母或数字,或者是!,之后有{0,}个>结尾,这个正则只能匹配出创建元素的情况,但不足以验证其内容的正确性,之后在方法里有验证其内容的正则表达式。zepto.fragment是来验证其内容的。因为很明显<2></2>也符合验证
if (selector[0] == '<' && fragmentRE.test(selector))
//下面的方法是来确认表达式,在创建元素,以后再展开吧。这里RegExp.$1为第一个子匹配(表达式中括号的部分)例如<p></p>匹配的就是p这样在fragment中p就是最外层的dom否则默认为div
dom = zepto.fragment(selector, RegExp.$1, context), selector = null
// $("#id","li")
else if (context !== undefined) return $(context).find(selector)
// $("#id")等我们常用的就在这个方法里
else dom = zepto.qsa(document, selector)
}
//最后都返回一个dom元素节点,是个数组类型的里面装有原型链方法,之后再说
如果是$(function(){})这个样式的就直接调用ready
else if (isFunction(selector)) return $(document).ready(selector)
// 传入的参数本身就已经是 zepto 对象,则直接返回
else if (zepto.isZ(selector)) return selector
else {
// compact函数:过滤掉为null的项
if (isArray(selector)) dom = compact(selector)
// 如果传入的是object,直接强制塞进一个数组
else if (isObject(selector)) dom = [selector], selector = null
// fragmentRE = /^\s*<(\w+|!)[^>]*>/ 还是取出第一个标签跟上面的差不多
else if (fragmentRE.test(selector))
dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
else if (context !== undefined) return $(context).find(selector)
else dom = zepto.qsa(document, selector)
}
return zepto.Z(dom, selector)
}
刚才上面的是一次初始化,主要是对于不同的写法干了不同的事,最后返回zepto.Z,我们看看这个函数
zepto.Z = function(dom, selector) {
dom = dom || []
//用过原型链的人知道这个__proto__ ,其实在自执行方法返回$的最后还有一段代码 zepto.Z.prototype = $.fn ,这样就是dom.__proto__ = zepto.Z.prototype,就相当于是构造函数实现原型链继承了。虽然自己继承自己,但应该是这么理解的。
dom.__proto__ = $.fn
dom.selector = selector || ''
return dom
}
最后返回的节点的样子就是
,有着各种方法的数组节点,方法都在$.fn中,下次在说说里面的方法,里面方法的写法读起来也收获良多。这次主要说的就是$("")
执行这段代码到底发生了什么,深深体会到了代码编写的路漫漫啊。
推荐阅读
-
Zepto.js之一步步看源码(一)
-
JAVA学习之一步步搭建spring框架
-
spring-boot-2.0.3不一样系列之源码篇 - run方法(四)之prepareContext,绝对有值得你看的地方
-
[Leveldb] 源码分析之一接口文件介绍
-
------ 开源软件 Tor(洋葱路由器,构建匿名网络的方案之一)源码分析——主程序入口点(二)------
-
怎么看一个网站源码是否值得使用?
-
spring-boot-2.0.3不一样系列之源码篇 - run方法(三)之createApplicationContext,绝对有值得你看的地方
-
Mybaits 源码解析 (十)----- 全网最详细,没有之一:Spring-Mybatis框架使用与源码解析
-
Mybaits 源码解析 (八)----- 全网最详细,没有之一:结果集 ResultSet 自动映射成实体类对象(上篇)
-
Mybaits 源码解析 (九)----- 全网最详细,没有之一:一级缓存和二级缓存源码分析