本文只分析核心的部分代码,并且在这部分代码有删减,但是不影响代码的正常运行。
目录
- * 用闭包封装Zepto
- * 开始处理细节
- * 正式处理数据(获取选择器选择的DOM)
- * 正式处理数据(添加DOM到当前实例)
- * 在实例的原型链上添加方法
- * 支持插件扩展
- * 验收
用闭包封装 Zepto
- // 对全局暴露Zepto变量
- var Zepto = (function() {
- // 定义$变量,并将具体细节交给zepto.init处理
- $ = function(selector, context) {
- return zepto.init(selector, context)
- }
- // 返回变量
- return $
- })()
- // 把Zepto变量挂载在window
- window.Zepto = Zepto
- // 当$变量没有被占用的时候,为Zepto设置别名为$
- window.$ === undefined && (window.$ = Zepto)
开始处理细节
- // 对全局暴露Zepto变量
- var Zepto = (function() {
- // [新增] 初始化zepto变量为对象
- var zepto = {}
- // [新增] 添加初始化方法。当selector参数为空时,则交给zepto.Z()处理
- // 当selector为字符串时则把zepto.qsa(document, selector)的值存到dom变量
- // 并且交给zepto.Z(dom, selector)处理
- zepto.init = function(selector, context) {
- var dom
- if (!selector) return zepto.Z()
- else if (typeof selector == 'string') {
- dom = zepto.qsa(document, selector)
- }
- return zepto.Z(dom, selector)
- }
- // 定义$变量,并将具体细节交给zepto.init处理
- $ = function(selector, context) {
- return zepto.init(selector, context)
- }
- // 返回变量
- return $
- })()
- // 把Zepto变量挂载在window
- window.Zepto = Zepto
- // 当$变量没有被占用的时候,为Zepto设置别名为$
- window.$ === undefined && (window.$ = Zepto)
正式处理数据(获取选择器选择的 DOM)
- // 对全局暴露Zepto变量
- var Zepto = (function() {
- // 初始化zepto变量为对象
- var zepto = {}
- // 添加初始化方法。当selector参数为空时,则交给zepto.Z()处理
- // 当selector为字符串时则把zepto.qsa(document, selector)的值存到dom变量
- // 并且交给zepto.Z(dom, selector)处理
- zepto.init = function(selector, context) {
- var dom
- if (!selector) return zepto.Z()
- else if (typeof selector == 'string') {
- dom = zepto.qsa(document, selector)
- }
- return zepto.Z(dom, selector)
- }
- // 定义$变量,并将具体细节交给zepto.init处理
- $ = function(selector, context) {
- return zepto.init(selector, context)
- }
- // [新增] 使用querySelectorAll(selector)查询DOM
- zepto.qsa = function(element, selector) {
- return selector ? element.querySelectorAll(selector) : []
- }
- // 返回变量
- return $
- })()
- // 把Zepto变量挂载在window
- window.Zepto = Zepto
- // 当$变量没有被占用的时候,为Zepto设置别名为$
- window.$ === undefined && (window.$ = Zepto)
正式处理数据(添加 DOM 到当前实例)
- // 对全局暴露Zepto变量
- var Zepto = (function() {
- // 初始化zepto变量为对象
- var zepto = {}
- // [新增] 开始正式处理数据。当dom长度为0则不添加内容,
- // 否则逐个将dom逐个到当前实例
- function Z(dom, selector) {
- var i, len = dom ? dom.length: 0
- for (i = 0; i < len; i++) this[i] = dom[i] this.length = len this.selector = selector || ''
- }
- // [新增] 直接返回一个新的构造函数
- zepto.Z = function(dom, selector) {
- return new Z(dom, selector)
- }
- // 添加初始化方法。当selector参数为空时,则交给zepto.Z()处理
- // 当selector为字符串时则把zepto.qsa(document, selector)的值存到dom变量
- // 并且交给zepto.Z(dom, selector)处理
- zepto.init = function(selector, context) {
- var dom
- if (!selector) return zepto.Z()
- else if (typeof selector == 'string') {
- dom = zepto.qsa(document, selector)
- }
- return zepto.Z(dom, selector)
- }
- // 定义$变量,并将具体细节交给zepto.init处理
- $ = function(selector, context) {
- return zepto.init(selector, context)
- }
- // 使用querySelectorAll(selector)查询DOM
- zepto.qsa = function(element, selector) {
- return selector ? element.querySelectorAll(selector) : []
- }
- // 返回变量
- return $
- })()
- // 把Zepto变量挂载在window
- window.Zepto = Zepto
- // 当$变量没有被占用的时候,为Zepto设置别名为$
- window.$ === undefined && (window.$ = Zepto)
在实例的原型链上添加方法
- // 对全局暴露Zepto变量
- var Zepto = (function() {
- // 初始化zepto变量为对象
- var zepto = {},
- emptyArray = []
- // 开始正式处理数据。当dom长度为0则不添加内容,
- // 否则逐个将dom逐个到当前实例
- function Z(dom, selector) {
- var i, len = dom ? dom.length: 0
- for (i = 0; i < len; i++) this[i] = dom[i] this.length = len this.selector = selector || ''
- }
- // 直接返回一个新的构造函数
- zepto.Z = function(dom, selector) {
- return new Z(dom, selector)
- }
- // 添加初始化方法。当selector参数为空时,则交给zepto.Z()处理
- // 当selector为字符串时则把zepto.qsa(document, selector)的值存到dom变量
- // 并且交给zepto.Z(dom, selector)处理
- zepto.init = function(selector, context) {
- var dom
- if (!selector) return zepto.Z()
- else if (typeof selector == 'string') {
- dom = zepto.qsa(document, selector)
- }
- return zepto.Z(dom, selector)
- }
- // 定义$变量,并将具体细节交给zepto.init处理
- $ = function(selector, context) {
- return zepto.init(selector, context)
- }
- // 使用querySelectorAll(selector)查询DOM
- zepto.qsa = function(element, selector) {
- return selector ? element.querySelectorAll(selector) : []
- }
- // [新增] 定义each方法
- $.each = function(elements, callback) {
- var i, key
- if (likeArray(elements)) {
- for (i = 0; i < elements.length; i++) if (callback.call(elements[i], i, elements[i]) === false) return elements
- } else {
- for (key in elements) if (callback.call(elements[key], key, elements[key]) === false) return elements
- }
- return elements
- }
- // [新增] 定义用于扩展在原型链上的方法
- $.fn = {
- constructor: zepto.Z,
- length: 0,
- each: function(callback) {
- emptyArray.every.call(this,
- function(el, idx) {
- return callback.call(el, idx, el) !== false
- }) return this
- },
- empty: function() {
- return this.each(function() {
- this.innerHTML = ''
- })
- },
- html: function(html) {
- return 0 in arguments ? this.each(function(idx) {
- var originHtml = this.innerHTML $(this).empty().append(funcArg(this, html, idx, originHtml))
- }) : (0 in this ? this[0].innerHTML: null)
- },
- test: function() {
- return this.each(function() {
- console.log('测试链式调用') return this
- })
- }
- }
- // [新增] 原型链指向$.fn
- zepto.Z.prototype = Z.prototype = $.fn
- // $.zepto指向zepto
- $.zepto = zepto
- // 返回变量
- return $
- })()
- // 把Zepto变量挂载在window
- window.Zepto = Zepto
- // 当$变量没有被占用的时候,为Zepto设置别名为$
- window.$ === undefined && (window.$ = Zepto)
支持插件扩展
- // 对全局暴露Zepto变量
- var Zepto = (function() {
- // 初始化zepto变量为对象
- var zepto = {},
- emptyArray = []
- // 开始正式处理数据。当dom长度为0则不添加内容,
- // 否则逐个将dom逐个到当前实例
- function Z(dom, selector) {
- var i, len = dom ? dom.length: 0
- for (i = 0; i < len; i++) this[i] = dom[i] this.length = len this.selector = selector || ''
- }
- // 直接返回一个新的构造函数
- zepto.Z = function(dom, selector) {
- return new Z(dom, selector)
- }
- // 添加初始化方法。当selector参数为空时,则交给zepto.Z()处理
- // 当selector为字符串时则把zepto.qsa(document, selector)的值存到dom变量
- // 并且交给zepto.Z(dom, selector)处理
- zepto.init = function(selector, context) {
- var dom
- if (!selector) return zepto.Z()
- else if (typeof selector == 'string') {
- dom = zepto.qsa(document, selector)
- }
- return zepto.Z(dom, selector)
- }
- // 定义$变量,并将具体细节交给zepto.init处理
- $ = function(selector, context) {
- return zepto.init(selector, context)
- }
- // [新增] 插件扩展函数
- function extend(target, source, deep) {
- for (key in source) if (source[key] !== undefined) target[key] = source[key]
- }
- // [新增] 插件扩展函数
- $.extend = function(target) {
- var deep, args = emptyArray.slice.call(arguments, 1) if (typeof target == 'boolean') {
- deep = target target = args.shift()
- }
- args.forEach(function(arg) {
- extend(target, arg, deep)
- }) return target
- }
- // 使用querySelectorAll(selector)查询DOM
- zepto.qsa = function(element, selector) {
- return selector ? element.querySelectorAll(selector) : []
- }
- // 定义each方法
- $.each = function(elements, callback) {
- var i, key
- if (likeArray(elements)) {
- for (i = 0; i < elements.length; i++) if (callback.call(elements[i], i, elements[i]) === false) return elements
- } else {
- for (key in elements) if (callback.call(elements[key], key, elements[key]) === false) return elements
- }
- return elements
- }
- // 定义用于扩展在原型链上的方法
- $.fn = {
- constructor: zepto.Z,
- length: 0,
- each: function(callback) {
- emptyArray.every.call(this,
- function(el, idx) {
- return callback.call(el, idx, el) !== false
- }) return this
- },
- empty: function() {
- return this.each(function() {
- this.innerHTML = ''
- })
- },
- html: function(html) {
- return 0 in arguments ? this.each(function(idx) {
- var originHtml = this.innerHTML $(this).empty().append(funcArg(this, html, idx, originHtml))
- }) : (0 in this ? this[0].innerHTML: null)
- },
- test: function() {
- return this.each(function() {
- console.log('测试链式调用') return this
- })
- }
- }
- // 原型链指向$.fn
- zepto.Z.prototype = Z.prototype = $.fn
- // $.zepto指向zepto
- $.zepto = zepto
- // 返回变量
- return $
- })()
- // 把Zepto变量挂载在window
- window.Zepto = Zepto
- // 当$变量没有被占用的时候,为Zepto设置别名为$
- window.$ === undefined && (window.$ = Zepto)
验收
- // 链式调用测试
- $('head').test().test() // 测试链式调用\n测试链式调用\n{0: head, length: 1, selector: "head"}
- $('head').html() // <meta charset="utf-8"><link rel="dns-prefetch" href...
- // 编写插件测试
- ; (function($) {
- $.extend($.fn, {
- bw2: function() {
- return this.html()
- }
- })
- })(Zepto) $('head').bw2() // <meta charset="utf-8"><link rel="dns-prefetch" href...
欢迎关注前端进阶指南微信公众号:
另外我也创了一个对应的 QQ 群:660112451,欢迎一起交流。
来源: http://www.cnblogs.com/bergwhite/p/7430946.html