graph LR A($) --- B(function) A($) --- C(zepto) A($) --- D(fn) C(zepto) --- CA(init) C(zepto) --- CB(Z) CB(Z) --> |new Z| E(Z) E(Z) -->|prototype| D(fn) B(function) -->|invoke| CA(init) CA(init) -->|invoke| CB(Z)

// ?????????
// ?????????
// ?
/* Zepto v1.2.0 - zepto event ajax form ie - zeptojs.com/license */
(function (global, factory) {if (typeof define === 'function' && define.amd)define(function () {return factory(global)})elsefactory(global)
}(this, function (window) {// ###########################################################################################################################// ###########################################################################################################################// ###########################################################################################################################var Zepto = (function () {// emptyArray = [] 可以方式每次有new一个Array对象// filter = emptyArray.filter// // filter.call([], function(){})// Array.prototype.filter.call([], function(){})// // 上面这种用法能很好的提高效率,免去了每次new一个对象的成本var undefined, key, $, classList, emptyArray = [],concat = emptyArray.concat,filter = emptyArray.filter,slice = emptyArray.slice,document = window.document,elementDisplay = {},classCache = {},cssNumber = {'column-count': 1,'columns': 1,'font-weight': 1,'line-height': 1,'opacity': 1,'z-index': 1,'zoom': 1},// 取出html代码中第一个html标签(或注释),如取出 <p>123</p><h1>345</h1> 中的 <p>fragmentRE = /^\s*<(\w+|!)[^>]*>/,// 匹配 <img /> <p></p>  不匹配 <img src=""/> <p>123</p>singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,// 匹配单标签tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,// 匹配 body html 顶级标签rootNodeRE = /^(?:body|html)$/i,// 匹配大写字母capitalRE = /([A-Z])/g,// special attributes that should be get/set via method calls// 这些属性可以通过方法进行设置methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],adjacencyOperators = ['after', 'prepend', 'before', 'append'],table = document.createElement('table'),tableRow = document.createElement('tr'),containers = {'tr': document.createElement('tbody'),'tbody': table,'thead': table,'tfoot': table,'td': tableRow,'th': tableRow,'*': document.createElement('div')},readyRE = /complete|loaded|interactive/,// 匹配一个包括(字母、数组、下划线、-)的字符串simpleSelectorRE = /^[\w-]*$/,class2type = {},toString = class2type.toString,// ?????????zepto = {},camelize, uniq,tempParent = document.createElement('div'),propMap = {'tabindex': 'tabIndex','readonly': 'readOnly','for': 'htmlFor','class': 'className','maxlength': 'maxLength','cellspacing': 'cellSpacing','cellpadding': 'cellPadding','rowspan': 'rowSpan','colspan': 'colSpan','usemap': 'useMap','frameborder': 'frameBorder','contenteditable': 'contentEditable'},// 判断是不是Array类型isArray = Array.isArray ||function (object) {return object instanceof Array}zepto.matches = function (element, selector) {// selector有值,element有值,并且element是普通DOM节点if (!selector || !element || element.nodeType !== 1) return falsevar matchesSelector = element.matches || element.webkitMatchesSelector ||element.mozMatchesSelector || element.oMatchesSelector ||element.matchesSelectorif (matchesSelector) return matchesSelector.call(element, selector)// fall back to performing a selector:var match, parent = element.parentNode,temp = !parentif (temp)(parent = tempParent).appendChild(element)match = ~zepto.qsa(parent, selector).indexOf(element)temp && tempParent.removeChild(element)return match}/*** class2type = {}* toString = class2type.toString* class2type[toString.call(obj)]* Object.prototype.toString.call() 就是 toString.call()* 为什么用最原始的 Object.prototype.toString.call()?* 如果我们new Array()后得到一个对象,我们直接调用它的toString()方法,会默认调用Array.prototype中的被重写的toString()方法。* 因此我们直接调用最顶层的toString()方法从而得到[object Array]* * 可以实验验证:* delete Array.prototype.toString* var arr = new Array()* arr.toString()* 执行上述代码则可以得到[object Array],就不是其重写的输出数组内全部元素的toString()方法了*//**$.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (i, name) {class2type["[object " + name + "]"] = name.toLowerCase()})*/function type(obj) {return obj == null ? String(obj) :class2type[toString.call(obj)] || "object"}// 判断是不是函数function isFunction(value) {return type(value) == "function"}// window的特点:window.window === windowfunction isWindow(obj) {return obj != null && obj == obj.window}// document.DOCUMENT_NODE的值是9, document.body == 1function isDocument(obj) {return obj != null && obj.nodeType == obj.DOCUMENT_NODE}/*** 判断是不是 Object*/function isObject(obj) {return type(obj) == "object"}// 不是window对象,并且其隐士原型指向Object的显示原型,也就是说是 var obj = {} 出来的function isPlainObject(obj) {return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype}// 判断是不是数组或者对象数组function likeArray(obj) {// Trick: true && true && 2 的结果为2var length = !!obj && 'length' in obj && obj.length, // 得到length的值type = $.type(obj) // 得到obj的具体类型return 'function' != type && !isWindow(obj) && ( // 首先obj不是function和window'array' == type || length === 0 ||(typeof length == 'number' && length > 0 && (length - 1) in obj)) // [length === 0:] true || true || false ; [length > 0:] true || false || true}// == 用来判断null和undefined两种类型,因此这里把数组中的这两种类型剔除function compact(array) {return filter.call(array, function (item) {return item != null})}// var a = ['abc']// var b = [].concat(a)// a === b : false// 这个方法类似得到一个数组的副本function flatten(array) {return array.length > 0 ? $.fn.concat.apply([], array) : array}// camelize-case/camelize--case ==> camelizeCasecamelize = function (str) {return str.replace(/-+(.)?/g, function (match, chr) {return chr ? chr.toUpperCase() : ''})}// 和上面方法正好相反,camelizeCase ==> camelize-casefunction dasherize(str) {return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase()}uniq = function (array) {return filter.call(array, function (item, idx) {return array.indexOf(item) == idx})}function classRE(name) {return name in classCache ?classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)'))}function maybeAddPx(name, value) {return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value}function defaultDisplay(nodeName) {var element, displayif (!elementDisplay[nodeName]) {element = document.createElement(nodeName)document.body.appendChild(element)display = getComputedStyle(element, '').getPropertyValue("display")element.parentNode.removeChild(element)display == "none" && (display = "block")elementDisplay[nodeName] = display}return elementDisplay[nodeName]}function children(element) {return 'children' in element ?slice.call(element.children) :$.map(element.childNodes, function (node) {if (node.nodeType == 1) return node})}// ?????????function Z(dom, selector) {/*** dom 是上一个方法取到的元素集合* 这里是将其转化成对象数组。obj{0: 'a', 1: 'b', length: 2} 的形式*/var i, len = dom ? dom.length : 0for (i = 0; i < len; i++) this[i] = dom[i]this.length = lenthis.selector = selector || ''}// `$.zepto.fragment` takes a html string and an optional tag name// to generate DOM nodes from the given html string.// The generated DOM nodes are returned as an array.// This function can be overridden in plugins for example to make// it compatible with browsers that don't support the DOM fully.zepto.fragment = function (html, name, properties) {var dom, nodes, container// A special case optimization for a single tagif (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))if (!dom) {if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")if (name === undefined) name = fragmentRE.test(html) && RegExp.$1if (!(name in containers)) name = '*'container = containers[name]container.innerHTML = '' + htmldom = $.each(slice.call(container.childNodes), function () {container.removeChild(this)})}if (isPlainObject(properties)) {nodes = $(dom)$.each(properties, function (key, value) {if (methodAttributes.indexOf(key) > -1) nodes[key](value)else nodes.attr(key, value)})}return dom}// `$.zepto.Z` swaps out the prototype of the given `dom` array// of nodes with `$.fn` and thus supplying all the Zepto functions// to the array. This method can be overridden in plugins.// ?????????zepto.Z = function (dom, selector) {var testzzz =  new Z(dom, selector)console.log(dom)console.log(testzzz)console.log(12121212)var bar = [{"a": "a"}, {"b": "b"}];var testzzz111 =  new Z(bar, selector)console.log(bar)console.log(testzzz111)console.log(testzzz111[0])return testzzz;}// `$.zepto.isZ` should return `true` if the given object is a Zepto// collection. This method can be overridden in plugins.zepto.isZ = function (object) {return object instanceof zepto.Z}// `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and// takes a CSS selector and an optional context (and handles various// special cases).// This method can be overridden in plugins.// ?????????/*** zepto,默认是接受两个参数的,第二个参数和第一个参数的值类型是一样的* 如果存在第二个参数的话,默认实在第二个参数中寻找第一个参数匹配的内容*/zepto.init = function (selector, context) {// debuggervar dom// If nothing given, return an empty Zepto collectionif (!selector) return zepto.Z()// ? 第一种情况,也就是我们常用的字符串选择器(标签名,id,class名)// Optimize for string selectorselse if (typeof selector == 'string') {selector = selector.trim()// If it's a html fragment, create nodes from it// Note: In both Chrome 21 and Firefox 15, DOM error 12// is thrown if the fragment doesn't begin with <if (selector[0] == '<' && fragmentRE.test(selector))dom = zepto.fragment(selector, RegExp.$1, context), selector = null// If there's a context, create a collection on that context first, and select// nodes from thereelse if (context !== undefined) return $(context).find(selector)// If it's a CSS selector, use it to select nodes.else dom = zepto.qsa(document, selector)}// ? 第二种情况,为 $(function(){}) 准备的// If a function is given, call it when the DOM is readyelse if (isFunction(selector)) return $(document).ready(selector)// ? 第三种情况,为重复选择准备的,如 $($('p'))// If a Zepto collection is given, just return itelse if (zepto.isZ(selector)) return selector// ? 第四种情况,else {// normalize array if an array of nodes is givenif (isArray(selector)) dom = compact(selector)// Wrap DOM nodes.else if (isObject(selector))dom = [selector], selector = null// If it's a html fragment, create nodes from itelse if (fragmentRE.test(selector))dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null// If there's a context, create a collection on that context first, and select// nodes from thereelse if (context !== undefined) return $(context).find(selector)// And last but no least, if it's a CSS selector, use it to select nodes.else dom = zepto.qsa(document, selector)}// create a new Zepto collection from the nodes foundreturn zepto.Z(dom, selector)}// `$` will be the base `Zepto` object. When calling this// function just call `$.zepto.init, which makes the implementation// details of selecting nodes and creating Zepto collections// patchable in plugins.// ?????????$ = function (selector, context) {return zepto.init(selector, context)}function extend(target, source, deep) {for (key in source)if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {if (isPlainObject(source[key]) && !isPlainObject(target[key]))target[key] = {}if (isArray(source[key]) && !isArray(target[key]))target[key] = []extend(target[key], source[key], deep)}else if (source[key] !== undefined) target[key] = source[key]}// Copy all but undefined properties from one or more// objects to the `target` object.$.extend = function (target) {var deep, args = slice.call(arguments, 1)if (typeof target == 'boolean') {deep = targettarget = args.shift()}args.forEach(function (arg) {extend(target, arg, deep)})return target}// `$.zepto.qsa` is Zepto's CSS selector implementation which// uses `document.querySelectorAll` and optimizes for some special cases, like `#id`.// This method can be overridden in plugins.// 三种情况:id选择器,css选择器,标签选择器 qsa => querySelectorAllzepto.qsa = function (element, selector) {var found,maybeID = selector[0] == '#',maybeClass = !maybeID && selector[0] == '.',// nameOnly = (maybeID || maybeClass) ? selector.slice(1) : selector, 如果是id选择器或者class选择器都要去除第一个字符得到字符串nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked// simpleSelectorRE = /^[\w-]*$/, 匹配一个包括(字母、数组、下划线、-)的字符串isSimple = simpleSelectorRE.test(nameOnly) // 就是匹配一个但word的字符串return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById// branch 1 按照id查找, [found] 保证所有返回取得原生dom对象都是一个数组((found = element.getElementById(nameOnly)) ? [found] : []) :// branch 2 按照class查找和按照tag名查找(element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] :slice.call(isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagNamemaybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a classelement.getElementsByTagName(selector) : // Or a tagelement.querySelectorAll(selector) // Or it's not simple, and we need to query all)}function filtered(nodes, selector) {return selector == null ? $(nodes) : $(nodes).filter(selector)}$.contains = document.documentElement.contains ?function (parent, node) {return parent !== node && parent.contains(node)} :function (parent, node) {while (node && (node = node.parentNode))if (node === parent) return truereturn false}function funcArg(context, arg, idx, payload) {return isFunction(arg) ? arg.call(context, idx, payload) : arg}// 封装原生操作的domsttr的方法function setAttribute(node, name, value) {value == null ? node.removeAttribute(name) : node.setAttribute(name, value)}// access className property while respecting SVGAnimatedStringfunction className(node, value) {var klass = node.className || '',svg = klass && klass.baseVal !== undefinedif (value === undefined) return svg ? klass.baseVal : klasssvg ? (klass.baseVal = value) : (node.className = value)}// "true"  => true// "false" => false// "null"  => null// "42"    => 42// "42.5"  => 42.5// "08"    => "08"// JSON    => parse if valid// String  => selffunction deserializeValue(value) {try {return value ?value == "true" ||(value == "false" ? false :value == "null" ? null :+value + "" == value ? +value :/^[\[\{]/.test(value) ? $.parseJSON(value) :value) :value} catch (e) {return value}}$.type = type$.isFunction = isFunction$.isWindow = isWindow$.isArray = isArray$.isPlainObject = isPlainObject// 这种判断方法是一旦进入循环,则表明对象里面有东西,说明对象不为空$.isEmptyObject = function (obj) {var namefor (name in obj) return falsereturn true}$.isNumeric = function (val) {var num = Number(val),type = typeof valreturn val != null && type != 'boolean' &&(type != 'string' || val.length) &&!isNaN(num) && isFinite(num) || false}$.inArray = function (elem, array, i) {return emptyArray.indexOf.call(array, elem, i)}$.camelCase = camelize$.trim = function (str) {return str == null ? "" : String.prototype.trim.call(str)}// plugin compatibility$.uuid = 0$.support = {}$.expr = {}$.noop = function () {}// 重新组织 elements 对象(数组、对象或者对象数组),针对每一个元素,都用 callback 进行检验// 检验通过后,将元素push进一个新数组,并返回/*$.map(arr, function(item, index){// do something})*/$.map = function (elements, callback) {var value, values = [],i, keyif (likeArray(elements)) // 处理正常数组for (i = 0; i < elements.length; i++) {value = callback(elements[i], i)if (value != null) values.push(value)}else // 处理对象数组for (key in elements) {value = callback(elements[key], key)if (value != null) values.push(value)}// flatten 函数上文定义的,作用:无论 values 是否是数组,都将返回一个正确的数组。例如,传入 'abc' ,返回 ['abc']return flatten(values)}/*$.each(arr, function(item, index){// do something})*/// === false) return elements 一旦有函数返回 false,即跳出循环$.each = function (elements, callback) {var i, keyif (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}// 数组自定义刷选方法 就是filter$.grep = function (elements, callback) {return filter.call(elements, callback)}if (window.JSON) $.parseJSON = JSON.parse// Populate the class2type map$.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (i, name) {class2type["[object " + name + "]"] = name.toLowerCase()})// Define methods that will be available on all// Zepto collections$.fn = {constructor: zepto.Z,length: 0,// Because a collection acts like an array// copy over these useful array functions.forEach: emptyArray.forEach,reduce: emptyArray.reduce,push: emptyArray.push,sort: emptyArray.sort,splice: emptyArray.splice,indexOf: emptyArray.indexOf,concat: function () {var i, value, args = []for (i = 0; i < arguments.length; i++) {value = arguments[i]args[i] = zepto.isZ(value) ? value.toArray() : value}return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)},// `map` and `slice` in the jQuery API work differently// from their array counterpartsmap: function (fn) {return $($.map(this, function (el, i) {return fn.call(el, i, el)}))},// 就是调用数组的silice并返回zepto对象slice: function () {return $(slice.apply(this, arguments))},ready: function (callback) {// need to check if document.body exists for IE as that browser reports// document ready when it hasn't yet created the body elementif (readyRE.test(document.readyState) && document.body) callback($)else document.addEventListener('DOMContentLoaded', function () {callback($)}, false)return this},// 提高get的兼容性,就算是输入负数,则表示从后往前找get: function (idx) {return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]},// 直接调用get方法toArray: function () {return this.get()},size: function () {return this.length},// 通过parentNode移除掉当前元素中的所有子元素remove: function () {return this.each(function () {if (this.parentNode != null)this.parentNode.removeChild(this)})},// 当前对象调用[].every方法,each: function (callback) {emptyArray.every.call(this, function (el, idx) {return callback.call(el, idx, el) !== false})return this},filter: function (selector) {if (isFunction(selector)) return this.not(this.not(selector))return $(filter.call(this, function (element) {return zepto.matches(element, selector)}))},// 构造一个新的zepto对象并加载当前对象数组中add: function (selector, context) {return $(uniq(this.concat($(selector, context))))},is: function (selector) {return this.length > 0 && zepto.matches(this[0], selector)},not: function (selector) {var nodes = []if (isFunction(selector) && selector.call !== undefined)this.each(function (idx) {if (!selector.call(this, idx)) nodes.push(this)})else {var excludes = typeof selector == 'string' ? this.filter(selector) :(likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)this.forEach(function (el) {if (excludes.indexOf(el) < 0) nodes.push(el)})}return $(nodes)},has: function (selector) {return this.filter(function () {return isObject(selector) ?$.contains(this, selector) :$(this).find(selector).size()})},eq: function (idx) {return idx === -1 ? this.slice(idx) : this.slice(idx, +idx + 1)},// 取集合中的第一条记录first: function () {var el = this[0]//如果集合中的第一条数据本身就已经是zepto对象则直接返回本身,否则转成zepto对象//el && !isObject(el)在这里取到一个判断el是否为节点的情况,因为如果el是节点,那么isObject(el)的结果就是truereturn el && !isObject(el) ? el : $(el)},// 取集合中的最后一条记录last: function () {var el = this[this.length - 1]return el && !isObject(el) ? el : $(el)},find: function (selector) {var result, $this = thisif (!selector) result = $()else if (typeof selector == 'object')result = $(selector).filter(function () {var node = thisreturn emptyArray.some.call($this, function (parent) {return $.contains(parent, node)})})else if (this.length == 1) result = $(zepto.qsa(this[0], selector))else result = this.map(function () {return zepto.qsa(this, selector)})return result},closest: function (selector, context) {var nodes = [],collection = typeof selector == 'object' && $(selector)this.each(function (_, node) {while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))node = node !== context && !isDocument(node) && node.parentNodeif (node && nodes.indexOf(node) < 0) nodes.push(node)})return $(nodes)},parents: function (selector) {var ancestors = [],nodes = thiswhile (nodes.length > 0)nodes = $.map(nodes, function (node) {if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {ancestors.push(node)return node}})return filtered(ancestors, selector)},parent: function (selector) {return filtered(uniq(this.pluck('parentNode')), selector)},children: function (selector) {return filtered(this.map(function () {return children(this)}), selector)},contents: function () {return this.map(function () {return this.contentDocument || slice.call(this.childNodes)})},siblings: function (selector) {return filtered(this.map(function (i, el) {return filter.call(children(el.parentNode), function (child) {return child !== el})}), selector)},empty: function () {return this.each(function () {this.innerHTML = ''})},// `pluck` is borrowed from Prototype.jspluck: function (property) {return $.map(this, function (el) {return el[property]})},show: function () {return this.each(function () {this.style.display == "none" && (this.style.display = '')if (getComputedStyle(this, '').getPropertyValue("display") == "none")this.style.display = defaultDisplay(this.nodeName)})},replaceWith: function (newContent) {return this.before(newContent).remove()},wrap: function (structure) {var func = isFunction(structure)if (this[0] && !func)var dom = $(structure).get(0),clone = dom.parentNode || this.length > 1return this.each(function (index) {$(this).wrapAll(func ? structure.call(this, index) :clone ? dom.cloneNode(true) : dom)})},wrapAll: function (structure) {if (this[0]) {$(this[0]).before(structure = $(structure))var children// drill down to the inmost elementwhile ((children = structure.children()).length) structure = children.first()$(structure).append(this)}return this},wrapInner: function (structure) {var func = isFunction(structure)return this.each(function (index) {var self = $(this),contents = self.contents(),dom = func ? structure.call(this, index) : structurecontents.length ? contents.wrapAll(dom) : self.append(dom)})},unwrap: function () {this.parent().each(function () {$(this).replaceWith($(this).children())})return this},clone: function () {return this.map(function () {return this.cloneNode(true)})},hide: function () {return this.css("display", "none")},toggle: function (setting) {return this.each(function () {var el = $(this);(setting === undefined ? el.css("display") == "none" : setting) ? el.show(): el.hide()})},prev: function (selector) {return $(this.pluck('previousElementSibling')).filter(selector || '*')},next: function (selector) {return $(this.pluck('nextElementSibling')).filter(selector || '*')},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)},text: function (text) {return 0 in arguments ?this.each(function (idx) {var newText = funcArg(this, text, idx, this.textContent)this.textContent = newText == null ? '' : '' + newText}) :(0 in this ? this.pluck('textContent').join("") : null)},attr: function (name, value) {var resultreturn (typeof name == 'string' && !(1 in arguments)) ?(0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) :this.each(function (idx) {if (this.nodeType !== 1) returnif (isObject(name))for (key in name) setAttribute(this, key, name[key])else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))})},removeAttr: function (name) {return this.each(function () {this.nodeType === 1 && name.split(' ').forEach(function (attribute) {setAttribute(this, attribute)}, this)})},prop: function (name, value) {name = propMap[name] || namereturn (1 in arguments) ?this.each(function (idx) {this[name] = funcArg(this, value, idx, this[name])}) :(this[0] && this[0][name])},removeProp: function (name) {name = propMap[name] || namereturn this.each(function () {delete this[name]})},data: function (name, value) {var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase()var data = (1 in arguments) ?this.attr(attrName, value) :this.attr(attrName)return data !== null ? deserializeValue(data) : undefined},val: function (value) {if (0 in arguments) {if (value == null) value = ""return this.each(function (idx) {this.value = funcArg(this, value, idx, this.value)})} else {return this[0] && (this[0].multiple ?$(this[0]).find('option').filter(function () {return this.selected}).pluck('value') :this[0].value)}},offset: function (coordinates) {if (coordinates) return this.each(function (index) {var $this = $(this),coords = funcArg(this, coordinates, index, $this.offset()),parentOffset = $this.offsetParent().offset(),props = {top: coords.top - parentOffset.top,left: coords.left - parentOffset.left}if ($this.css('position') == 'static') props['position'] = 'relative'$this.css(props)})if (!this.length) return nullif (document.documentElement !== this[0] && !$.contains(document.documentElement, this[0]))return {top: 0,left: 0}var obj = this[0].getBoundingClientRect()return {left: obj.left + window.pageXOffset,top: obj.top + window.pageYOffset,width: Math.round(obj.width),height: Math.round(obj.height)}},css: function (property, value) {if (arguments.length < 2) {var element = this[0]if (typeof property == 'string') {if (!element) returnreturn element.style[camelize(property)] || getComputedStyle(element, '').getPropertyValue(property)} else if (isArray(property)) {if (!element) returnvar props = {}var computedStyle = getComputedStyle(element, '')$.each(property, function (_, prop) {props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop))})return props}}var css = ''if (type(property) == 'string') {if (!value && value !== 0)this.each(function () {this.style.removeProperty(dasherize(property))})elsecss = dasherize(property) + ":" + maybeAddPx(property, value)} else {for (key in property)if (!property[key] && property[key] !== 0)this.each(function () {this.style.removeProperty(dasherize(key))})elsecss += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';'}return this.each(function () {this.style.cssText += ';' + css})},index: function (element) {return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])},hasClass: function (name) {if (!name) return falsereturn emptyArray.some.call(this, function (el) {return this.test(className(el))}, classRE(name))},addClass: function (name) {if (!name) return thisreturn this.each(function (idx) {if (!('className' in this)) returnclassList = []var cls = className(this),newName = funcArg(this, name, idx, cls)newName.split(/\s+/g).forEach(function (klass) {if (!$(this).hasClass(klass)) classList.push(klass)}, this)classList.length && className(this, cls + (cls ? " " : "") + classList.join(" "))})},removeClass: function (name) {return this.each(function (idx) {if (!('className' in this)) returnif (name === undefined) return className(this, '')classList = className(this)funcArg(this, name, idx, classList).split(/\s+/g).forEach(function (klass) {classList = classList.replace(classRE(klass), " ")})className(this, classList.trim())})},toggleClass: function (name, when) {if (!name) return thisreturn this.each(function (idx) {var $this = $(this),names = funcArg(this, name, idx, className(this))names.split(/\s+/g).forEach(function (klass) {(when === undefined ? !$this.hasClass(klass) : when) ?$this.addClass(klass): $this.removeClass(klass)})})},scrollTop: function (value) {if (!this.length) returnvar hasScrollTop = 'scrollTop' in this[0]if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffsetreturn this.each(hasScrollTop ?function () {this.scrollTop = value} :function () {this.scrollTo(this.scrollX, value)})},scrollLeft: function (value) {if (!this.length) returnvar hasScrollLeft = 'scrollLeft' in this[0]if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffsetreturn this.each(hasScrollLeft ?function () {this.scrollLeft = value} :function () {this.scrollTo(value, this.scrollY)})},position: function () {if (!this.length) returnvar elem = this[0],// Get *real* offsetParentoffsetParent = this.offsetParent(),// Get correct offsetsoffset = this.offset(),parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? {top: 0,left: 0} : offsetParent.offset()// Subtract element margins// note: when an element has margin: auto the offsetLeft and marginLeft// are the same in Safari causing offset.left to incorrectly be 0offset.top -= parseFloat($(elem).css('margin-top')) || 0offset.left -= parseFloat($(elem).css('margin-left')) || 0// Add offsetParent bordersparentOffset.top += parseFloat($(offsetParent[0]).css('border-top-width')) || 0parentOffset.left += parseFloat($(offsetParent[0]).css('border-left-width')) || 0// Subtract the two offsetsreturn {top: offset.top - parentOffset.top,left: offset.left - parentOffset.left}},offsetParent: function () {return this.map(function () {var parent = this.offsetParent || document.bodywhile (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static")parent = parent.offsetParentreturn parent})}}// for now$.fn.detach = $.fn.remove// Generate the `width` and `height` functions;['width', 'height'].forEach(function (dimension) {var dimensionProperty =dimension.replace(/./, function (m) {return m[0].toUpperCase()})$.fn[dimension] = function (value) {var offset, el = this[0]if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] :isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :(offset = this.offset()) && offset[dimension]else return this.each(function (idx) {el = $(this)el.css(dimension, funcArg(this, value, idx, el[dimension]()))})}})function traverseNode(node, fun) {fun(node)for (var i = 0, len = node.childNodes.length; i < len; i++)traverseNode(node.childNodes[i], fun)}// Generate the `after`, `prepend`, `before`, `append`,// `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods.adjacencyOperators.forEach(function (operator, operatorIndex) {var inside = operatorIndex % 2 //=> prepend, append$.fn[operator] = function () {// arguments can be nodes, arrays of nodes, Zepto objects and HTML stringsvar argType, nodes = $.map(arguments, function (arg) {var arr = []argType = type(arg)if (argType == "array") {arg.forEach(function (el) {if (el.nodeType !== undefined) return arr.push(el)else if ($.zepto.isZ(el)) return arr = arr.concat(el.get())arr = arr.concat(zepto.fragment(el))})return arr}return argType == "object" || arg == null ?arg : zepto.fragment(arg)}),parent, copyByClone = this.length > 1if (nodes.length < 1) return thisreturn this.each(function (_, target) {parent = inside ? target : target.parentNode// convert all methods to a "before" operationtarget = operatorIndex == 0 ? target.nextSibling :operatorIndex == 1 ? target.firstChild :operatorIndex == 2 ? target :nullvar parentInDocument = $.contains(document.documentElement, parent)nodes.forEach(function (node) {if (copyByClone) node = node.cloneNode(true)else if (!parent) return $(node).remove()parent.insertBefore(node, target)if (parentInDocument) traverseNode(node, function (el) {if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&(!el.type || el.type === 'text/javascript') && !el.src) {var target = el.ownerDocument ? el.ownerDocument.defaultView : windowtarget['eval'].call(target, el.innerHTML)}})})})}// after    => insertAfter// prepend  => prependTo// before   => insertBefore// append   => appendTo$.fn[inside ? operator + 'To' : 'insert' + (operatorIndex ? 'Before' : 'After')] = function (html) {$(html)[operator](this)return this}})// ?????????zepto.Z.prototype = Z.prototype = $.fn// Export internal API functions in the `$.zepto` namespacezepto.uniq = uniqzepto.deserializeValue = deserializeValue$.zepto = zeptoreturn $})()window.Zepto = Zeptowindow.$ === undefined && (window.$ = Zepto)// Where Zepto start// ###########################################################################################################################// ###########################################################################################################################// ###########################################################################################################################/*** * * */;(function ($) {var _zid = 1,undefined,slice = Array.prototype.slice,isFunction = $.isFunction,isString = function (obj) {return typeof obj == 'string'},handlers = {},specialEvents = {},focusinSupported = 'onfocusin' in window,focus = {focus: 'focusin',blur: 'focusout'},hover = {mouseenter: 'mouseover',mouseleave: 'mouseout'}specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents'function zid(element) {return element._zid || (element._zid = _zid++)}function findHandlers(element, event, fn, selector) {event = parse(event)if (event.ns) var matcher = matcherFor(event.ns)return (handlers[zid(element)] || []).filter(function (handler) {return handler &&(!event.e || handler.e == event.e) &&(!event.ns || matcher.test(handler.ns)) &&(!fn || zid(handler.fn) === zid(fn)) &&(!selector || handler.sel == selector)})}function parse(event) {var parts = ('' + event).split('.')return {e: parts[0],ns: parts.slice(1).sort().join(' ')}}function matcherFor(ns) {return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)')}function eventCapture(handler, captureSetting) {return handler.del &&(!focusinSupported && (handler.e in focus)) ||!!captureSetting}function realEvent(type) {return hover[type] || (focusinSupported && focus[type]) || type}function add(element, events, fn, data, selector, delegator, capture) {var id = zid(element),set = (handlers[id] || (handlers[id] = []))events.split(/\s/).forEach(function (event) {if (event == 'ready') return $(document).ready(fn)var handler = parse(event)handler.fn = fnhandler.sel = selector// emulate mouseenter, mouseleaveif (handler.e in hover) fn = function (e) {var related = e.relatedTargetif (!related || (related !== this && !$.contains(this, related)))return handler.fn.apply(this, arguments)}handler.del = delegatorvar callback = delegator || fnhandler.proxy = function (e) {e = compatible(e)if (e.isImmediatePropagationStopped()) returne.data = datavar result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args))if (result === false) e.preventDefault(), e.stopPropagation()return result}handler.i = set.lengthset.push(handler)if ('addEventListener' in element)element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))})}function remove(element, events, fn, selector, capture) {var id = zid(element);(events || '').split(/\s/).forEach(function (event) {findHandlers(element, event, fn, selector).forEach(function (handler) {delete handlers[id][handler.i]if ('removeEventListener' in element)element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture))})})}$.event = {add: add,remove: remove}$.proxy = function (fn, context) {var args = (2 in arguments) && slice.call(arguments, 2)if (isFunction(fn)) {var proxyFn = function () {return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments)}proxyFn._zid = zid(fn)return proxyFn} else if (isString(context)) {if (args) {args.unshift(fn[context], fn)return $.proxy.apply(null, args)} else {return $.proxy(fn[context], fn)}} else {throw new TypeError("expected function")}}$.fn.bind = function (event, data, callback) {return this.on(event, data, callback)}$.fn.unbind = function (event, callback) {return this.off(event, callback)}$.fn.one = function (event, selector, data, callback) {return this.on(event, selector, data, callback, 1)}var returnTrue = function () {return true},returnFalse = function () {return false},ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/,eventMethods = {preventDefault: 'isDefaultPrevented',stopImmediatePropagation: 'isImmediatePropagationStopped',stopPropagation: 'isPropagationStopped'}function compatible(event, source) {if (source || !event.isDefaultPrevented) {source || (source = event)$.each(eventMethods, function (name, predicate) {var sourceMethod = source[name]event[name] = function () {this[predicate] = returnTruereturn sourceMethod && sourceMethod.apply(source, arguments)}event[predicate] = returnFalse})event.timeStamp || (event.timeStamp = Date.now())if (source.defaultPrevented !== undefined ? source.defaultPrevented :'returnValue' in source ? source.returnValue === false :source.getPreventDefault && source.getPreventDefault())event.isDefaultPrevented = returnTrue}return event}function createProxy(event) {var key, proxy = {originalEvent: event}for (key in event)if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key]return compatible(proxy, event)}$.fn.delegate = function (selector, event, callback) {return this.on(event, selector, callback)}$.fn.undelegate = function (selector, event, callback) {return this.off(event, selector, callback)}$.fn.live = function (event, callback) {$(document.body).delegate(this.selector, event, callback)return this}$.fn.die = function (event, callback) {$(document.body).undelegate(this.selector, event, callback)return this}$.fn.on = function (event, selector, data, callback, one) {var autoRemove, delegator, $this = thisif (event && !isString(event)) {$.each(event, function (type, fn) {$this.on(type, selector, data, fn, one)})return $this}if (!isString(selector) && !isFunction(callback) && callback !== false)callback = data, data = selector, selector = undefinedif (callback === undefined || data === false)callback = data, data = undefinedif (callback === false) callback = returnFalsereturn $this.each(function (_, element) {if (one) autoRemove = function (e) {remove(element, e.type, callback)return callback.apply(this, arguments)}if (selector) delegator = function (e) {var evt, match = $(e.target).closest(selector, element).get(0)if (match && match !== element) {evt = $.extend(createProxy(e), {currentTarget: match,liveFired: element})return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1)))}}add(element, event, callback, data, selector, delegator || autoRemove)})}$.fn.off = function (event, selector, callback) {var $this = thisif (event && !isString(event)) {$.each(event, function (type, fn) {$this.off(type, selector, fn)})return $this}if (!isString(selector) && !isFunction(callback) && callback !== false)callback = selector, selector = undefinedif (callback === false) callback = returnFalsereturn $this.each(function () {remove(this, event, callback, selector)})}$.fn.trigger = function (event, args) {event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event)event._args = argsreturn this.each(function () {// handle focus(), blur() by calling them directlyif (event.type in focus && typeof this[event.type] == "function") this[event.type]()// items in the collection might not be DOM elementselse if ('dispatchEvent' in this) this.dispatchEvent(event)else $(this).triggerHandler(event, args)})}// triggers event handlers on current element just as if an event occurred,// doesn't trigger an actual event, doesn't bubble$.fn.triggerHandler = function (event, args) {var e, resultthis.each(function (i, element) {e = createProxy(isString(event) ? $.Event(event) : event)e._args = argse.target = element$.each(findHandlers(element, event.type || event), function (i, handler) {result = handler.proxy(e)if (e.isImmediatePropagationStopped()) return false})})return result}// shortcut methods for `.bind(event, fn)` for each event type;('focusin focusout focus blur load resize scroll unload click dblclick ' +'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave ' +'change select keydown keypress keyup error').split(' ').forEach(function (event) {$.fn[event] = function (callback) {return (0 in arguments) ?this.bind(event, callback) :this.trigger(event)}})$.Event = function (type, props) {if (!isString(type)) props = type, type = props.typevar event = document.createEvent(specialEvents[type] || 'Events'),bubbles = trueif (props)for (var name in props)(name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name])event.initEvent(type, bubbles, true)return compatible(event)}})(Zepto);(function ($) {var jsonpID = +new Date(),document = window.document,key,name,rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,scriptTypeRE = /^(?:text|application)\/javascript/i,xmlTypeRE = /^(?:text|application)\/xml/i,jsonType = 'application/json',htmlType = 'text/html',blankRE = /^\s*$/,originAnchor = document.createElement('a')originAnchor.href = window.location.href// trigger a custom event and return false if it was cancelledfunction triggerAndReturn(context, eventName, data) {var event = $.Event(eventName)$(context).trigger(event, data)return !event.isDefaultPrevented()}// trigger an Ajax "global" eventfunction triggerGlobal(settings, context, eventName, data) {if (settings.global) return triggerAndReturn(context || document, eventName, data)}// Number of active Ajax requests$.active = 0function ajaxStart(settings) {if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart')}function ajaxStop(settings) {if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop')}// triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelablefunction ajaxBeforeSend(xhr, settings) {var context = settings.contextif (settings.beforeSend.call(context, xhr, settings) === false ||triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false)return falsetriggerGlobal(settings, context, 'ajaxSend', [xhr, settings])}function ajaxSuccess(data, xhr, settings, deferred) {var context = settings.context,status = 'success'settings.success.call(context, data, status, xhr)if (deferred) deferred.resolveWith(context, [data, status, xhr])triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data])ajaxComplete(status, xhr, settings)}// type: "timeout", "error", "abort", "parsererror"function ajaxError(error, type, xhr, settings, deferred) {var context = settings.contextsettings.error.call(context, xhr, type, error)if (deferred) deferred.rejectWith(context, [xhr, type, error])triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type])ajaxComplete(type, xhr, settings)}// status: "success", "notmodified", "error", "timeout", "abort", "parsererror"function ajaxComplete(status, xhr, settings) {var context = settings.contextsettings.complete.call(context, xhr, status)triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings])ajaxStop(settings)}function ajaxDataFilter(data, type, settings) {if (settings.dataFilter == empty) return datavar context = settings.contextreturn settings.dataFilter.call(context, data, type)}// Empty function, used as default callbackfunction empty() {}$.ajaxJSONP = function (options, deferred) {if (!('type' in options)) return $.ajax(options)var _callbackName = options.jsonpCallback,callbackName = ($.isFunction(_callbackName) ?_callbackName() : _callbackName) || ('Zepto' + (jsonpID++)),script = document.createElement('script'),originalCallback = window[callbackName],responseData,abort = function (errorType) {$(script).triggerHandler('error', errorType || 'abort')},xhr = {abort: abort},abortTimeoutif (deferred) deferred.promise(xhr)$(script).on('load error', function (e, errorType) {clearTimeout(abortTimeout)$(script).off().remove()if (e.type == 'error' || !responseData) {ajaxError(null, errorType || 'error', xhr, options, deferred)} else {ajaxSuccess(responseData[0], xhr, options, deferred)}window[callbackName] = originalCallbackif (responseData && $.isFunction(originalCallback))originalCallback(responseData[0])originalCallback = responseData = undefined})if (ajaxBeforeSend(xhr, options) === false) {abort('abort')return xhr}window[callbackName] = function () {responseData = arguments}script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName)document.head.appendChild(script)if (options.timeout > 0) abortTimeout = setTimeout(function () {abort('timeout')}, options.timeout)return xhr}$.ajaxSettings = {// Default type of requesttype: 'GET',// Callback that is executed before requestbeforeSend: empty,// Callback that is executed if the request succeedssuccess: empty,// Callback that is executed the the server drops errorerror: empty,// Callback that is executed on request complete (both: error and success)complete: empty,// The context for the callbackscontext: null,// Whether to trigger "global" Ajax eventsglobal: true,// Transportxhr: function () {return new window.XMLHttpRequest()},// MIME types mapping// IIS returns Javascript as "application/x-javascript"accepts: {script: 'text/javascript, application/javascript, application/x-javascript',json: jsonType,xml: 'application/xml, text/xml',html: htmlType,text: 'text/plain'},// Whether the request is to another domaincrossDomain: false,// Default timeouttimeout: 0,// Whether data should be serialized to stringprocessData: true,// Whether the browser should be allowed to cache GET responsescache: true,//Used to handle the raw response data of XMLHttpRequest.//This is a pre-filtering function to sanitize the response.//The sanitized response should be returneddataFilter: empty}function mimeToDataType(mime) {if (mime) mime = mime.split(';', 2)[0]return mime && (mime == htmlType ? 'html' :mime == jsonType ? 'json' :scriptTypeRE.test(mime) ? 'script' :xmlTypeRE.test(mime) && 'xml') || 'text'}function appendQuery(url, query) {if (query == '') return urlreturn (url + '&' + query).replace(/[&?]{1,2}/, '?')}// serialize payload and append it to the URL for GET requestsfunction serializeData(options) {if (options.processData && options.data && $.type(options.data) != "string")options.data = $.param(options.data, options.traditional)if (options.data && (!options.type || options.type.toUpperCase() == 'GET' || 'jsonp' == options.dataType))options.url = appendQuery(options.url, options.data), options.data = undefined}$.ajax = function (options) {var settings = $.extend({}, options || {}),deferred = $.Deferred && $.Deferred(),urlAnchor, hashIndexfor (key in $.ajaxSettings)if (settings[key] === undefined) settings[key] = $.ajaxSettings[key]ajaxStart(settings)if (!settings.crossDomain) {urlAnchor = document.createElement('a')urlAnchor.href = settings.url// cleans up URL for .href (IE only), see https://github.com/madrobby/zepto/pull/1049urlAnchor.href = urlAnchor.hrefsettings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host)}if (!settings.url) settings.url = window.location.toString()if ((hashIndex = settings.url.indexOf('#')) > -1) settings.url = settings.url.slice(0, hashIndex)serializeData(settings)var dataType = settings.dataType,hasPlaceholder = /\?.+=\?/.test(settings.url)if (hasPlaceholder) dataType = 'jsonp'if (settings.cache === false || ((!options || options.cache !== true) &&('script' == dataType || 'jsonp' == dataType)))settings.url = appendQuery(settings.url, '_=' + Date.now())if ('jsonp' == dataType) {if (!hasPlaceholder)settings.url = appendQuery(settings.url,settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')return $.ajaxJSONP(settings, deferred)}var mime = settings.accepts[dataType],headers = {},setHeader = function (name, value) {headers[name.toLowerCase()] = [name, value]},protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol,xhr = settings.xhr(),nativeSetHeader = xhr.setRequestHeader,abortTimeoutif (deferred) deferred.promise(xhr)if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest')setHeader('Accept', mime || '*/*')if (mime = settings.mimeType || mime) {if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0]xhr.overrideMimeType && xhr.overrideMimeType(mime)}if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded')if (settings.headers)for (name in settings.headers) setHeader(name, settings.headers[name])xhr.setRequestHeader = setHeaderxhr.onreadystatechange = function () {if (xhr.readyState == 4) {xhr.onreadystatechange = emptyclearTimeout(abortTimeout)var result, error = falseif ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) {dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'))if (xhr.responseType == 'arraybuffer' || xhr.responseType == 'blob')result = xhr.responseelse {result = xhr.responseTexttry {// http://perfectionkills.com/global-eval-what-are-the-options/// sanitize response accordingly if data filter callback providedresult = ajaxDataFilter(result, dataType, settings)if (dataType == 'script')(1, eval)(result)else if (dataType == 'xml') result = xhr.responseXMLelse if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result)} catch (e) {error = e}if (error) return ajaxError(error, 'parsererror', xhr, settings, deferred)}ajaxSuccess(result, xhr, settings, deferred)} else {ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred)}}}if (ajaxBeforeSend(xhr, settings) === false) {xhr.abort()ajaxError(null, 'abort', xhr, settings, deferred)return xhr}var async = 'async' in settings ? settings.async : truexhr.open(settings.type, settings.url, async, settings.username, settings.password)if (settings.xhrFields)for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name]for (name in headers) nativeSetHeader.apply(xhr, headers[name])if (settings.timeout > 0) abortTimeout = setTimeout(function () {xhr.onreadystatechange = emptyxhr.abort()ajaxError(null, 'timeout', xhr, settings, deferred)}, settings.timeout)// avoid sending empty string (#319)xhr.send(settings.data ? settings.data : null)return xhr}// handle optional data/success argumentsfunction parseArguments(url, data, success, dataType) {if ($.isFunction(data)) dataType = success, success = data, data = undefinedif (!$.isFunction(success)) dataType = success, success = undefinedreturn {url: url,data: data,success: success,dataType: dataType}}$.get = function ( /* url, data, success, dataType */ ) {return $.ajax(parseArguments.apply(null, arguments))}$.post = function ( /* url, data, success, dataType */ ) {var options = parseArguments.apply(null, arguments)options.type = 'POST'return $.ajax(options)}$.getJSON = function ( /* url, data, success */ ) {var options = parseArguments.apply(null, arguments)options.dataType = 'json'return $.ajax(options)}$.fn.load = function (url, data, success) {if (!this.length) return thisvar self = this,parts = url.split(/\s/),selector,options = parseArguments(url, data, success),callback = options.successif (parts.length > 1) options.url = parts[0], selector = parts[1]options.success = function (response) {self.html(selector ?$('<div>').html(response.replace(rscript, "")).find(selector) :response)callback && callback.apply(self, arguments)}$.ajax(options)return this}var escape = encodeURIComponentfunction serialize(params, obj, traditional, scope) {var type, array = $.isArray(obj),hash = $.isPlainObject(obj)$.each(obj, function (key, value) {type = $.type(value)if (scope) key = traditional ? scope :scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']'// handle data in serializeArray() formatif (!scope && array) params.add(value.name, value.value)// recurse into nested objectselse if (type == "array" || (!traditional && type == "object"))serialize(params, value, traditional, key)else params.add(key, value)})}$.param = function (obj, traditional) {var params = []params.add = function (key, value) {if ($.isFunction(value)) value = value()if (value == null) value = ""this.push(escape(key) + '=' + escape(value))}serialize(params, obj, traditional)return params.join('&').replace(/%20/g, '+')}})(Zepto);(function ($) {$.fn.serializeArray = function () {var name, type, result = [],add = function (value) {if (value.forEach) return value.forEach(add)result.push({name: name,value: value})}if (this[0]) $.each(this[0].elements, function (_, field) {type = field.type, name = field.nameif (name && field.nodeName.toLowerCase() != 'fieldset' &&!field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' &&((type != 'radio' && type != 'checkbox') || field.checked))add($(field).val())})return result}$.fn.serialize = function () {var result = []this.serializeArray().forEach(function (elm) {result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value))})return result.join('&')}$.fn.submit = function (callback) {if (0 in arguments) this.bind('submit', callback)else if (this.length) {var event = $.Event('submit')this.eq(0).trigger(event)if (!event.isDefaultPrevented()) this.get(0).submit()}return this}})(Zepto);(function () {// getComputedStyle shouldn't freak out when called// without a valid element as argumenttry {getComputedStyle(undefined)} catch (e) {var nativeGetComputedStyle = getComputedStylewindow.getComputedStyle = function (element, pseudoElement) {try {return nativeGetComputedStyle(element, pseudoElement)} catch (e) {return null}}}})()return Zepto
}))

转载于:https://www.cnblogs.com/steadfast-JSer/p/9971629.html

Zepto.js 源码解析(emoji版)相关推荐

  1. 【Vue.js源码解析 一】-- 响应式原理

    前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:建议通过左侧导航栏进行阅读 课程目标 Vue.js 的静态成员和实例成员初始化过程 首次渲染的过程 数据响应式原理 – 最核心的特性之一 准备工作 ...

  2. js define函数_不夸张,这真的是前端圈宝藏书!360前端工程师Vue.js源码解析

    优秀源代码背后的思想是永恒的.普适的. 这些年来,前端行业一直在飞速发展.行业的进步,导致对从业人员的要求不断攀升.放眼未来,虽然仅仅会用某些框架还可以找到工作,但仅仅满足于会用,一定无法走得更远.随 ...

  3. js怎么调用wasm_Long.js源码解析

    基于现在市面上到处都是 Vue/React 之类的源码分析文章实在是太多了.(虽然我也写过 Vite的源码解析 所以这次来写点不一样的.由于微信这边用的是 protobuf 来进行 rpc 调用.所以 ...

  4. JavaScript数字运算必备库——big.js源码解析

    概述 在我们常见的JavaScript数字运算中,小数和大数都是会让我们比较头疼的两个数据类型. 在大数运算中,由于number类型的数字长度限制,我们经常会遇到超出范围的情况.比如在我们传递Long ...

  5. video.js 源码解析

    为什么80%的码农都做不了架构师?>>>    写在前面 现在视频业务越来越流行了,播放器也比较多,作为前端工程师如何打造一个属于自己的播放器呢?最快最有效的方式是基于开源播放器深度 ...

  6. 如何将文件地址转为url_Node.js 源码解析 util.promisify 如何将 Callback 转为 Promise

    Nodejs util 模块提供了很多工具函数.为了解决回调地狱问题,Nodejs v8.0.0 提供了 promisify 方法可以将 Callback 转为 Promise 对象. 工作中对于一些 ...

  7. connect.js源码解析

    前言 众所周知,connect是TJ大神所造的一个大轮子,是大家用尾式调用来控制异步流程时最常使用的库,也是后来著名的express框架的本源.但令人惊讶的是,它的源码其实只有200多行,今天也来解析 ...

  8. 【Vue.js源码解析 三】-- 模板编译和组件化

    前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:建议通过左侧导航栏进行阅读 模板编译 模板编译的主要目的是将模板 (template) 转换为渲染函数 (render) <div> ...

  9. addEvent.js源码解析

    露露 前言: 看两三遍即可. 在看 jQuery 源码时,发现了这段注释: //源码5235行 /* * Helper functions for managing events -- not par ...

最新文章

  1. 【UIDynamic例子】挂起的方块
  2. ARM7+PROTEUS调试(转)
  3. 搜索引擎设计实用教程(3)-以百度为例 之三:对百度分词算法的进一步分析
  4. Jquery-core.holdReady()
  5. mysql数据太大,如何导入_MySQL导入文件过大怎么办
  6. 一个非常简单的滚动代码
  7. 饥荒进地洞服务器无响应,饥荒联机洞穴设置及常见问题的解决方法
  8. 轮盘赌算法的java实现算例
  9. 吴恩达深度学习之五《序列模型》学习笔记
  10. 1.[精通Hibernate笔记]Hibernate简介
  11. 【java笔记】hello world入门程序
  12. jdk中ArrayList的实现
  13. 顺通车间扫码出入库管理系统仓库扫码软件
  14. python做计量经济学的书籍_《计量经济学》教材书单
  15. baguetteBox.js - 简单易用的 lightbox 插件
  16. NLPIR-JAVA版本-MAC-LINUX-WINDOWS操作系统均适用
  17. 2021-2027全球及中国工业物联网通信产品行业研究及十四五规划分析报告
  18. Android-使用HttpURLConnection实现多线程下载
  19. AR技术应用 の 如何做一个Pokemon GO这只皮卡丘是你的吗?
  20. 当年明月《明朝那些事儿》读书笔记

热门文章

  1. Advanced Custom Fields Pro 自定义文章字段 wordpress插件
  2. mysql内部参数是什么意思_mysql参数及解释
  3. android8支持设备,Android8.0奥利奥支持机型有哪些 安卓8.0奥利奥适合设备详细介绍...
  4. flex简单常用笔记
  5. 红盟云卡v1.6.2源码
  6. 智慧城市同城V4小程序独立版v1.6.5+前端
  7. PHP+SQLite3简约网址导航、书签管理器网站源码
  8. wordpress插件-WP Rocket 3.10.1_去广告已授权
  9. Microsoft ScriptControl 控件使用指南
  10. CSS、JavaScript和Ajax实现图片预加载的三大方法及优缺点分析