您的位置:首页 > 编程语言

Zepto源码分析(一)核心代码分析

2017-08-26 02:00 585 查看
Zepto源码分析(一)核心代码分析

Zepto源码分析(二)奇淫技巧总结

本文只分析核心的部分代码,并且在这部分代码有删减,但是不影响代码的正常运行。


目录


* 用闭包封装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,欢迎一起交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: