Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api。 如果你会用jquery,那么你也会用zepto。
Zepto的设计目的是提供 jQuery 的类似的API,但并不是100%覆盖 jQuery 。所以会有些jQuery的动画功能Zepto实现不了,例如fade动画,但官方提供了解决办法,
主要是通过引入两个js插件:animate.js,zepto.animate.alias.js来实现完整的动画功能:
zepto.animate.alias.js:
/** * zepto.animate.alias.js */ (function($) { $.extend($.fn, { fadeIn: function(speed, easing, complete) { if(typeof(speed) === 'undefined') speed = 400; if(typeof(easing) === 'undefined') { easing = 'swing'; } else if(typeof(easing) === 'function') { if(typeof(complete) === 'undefined') complete = easing; easing = 'swing'; } $(this).css({ display: 'block', opacity: 0 }).animate({ opacity: 1 }, speed, easing, function() { // complete callback complete && typeof(complete) === 'function' && complete(); }); return this; }, fadeOut: function(speed, easing, complete) { if(typeof(speed) === 'undefined') speed = 400; if(typeof(easing) === 'undefined') { easing = 'swing'; } else if(typeof(easing) === 'function') { if(typeof(complete) === 'undefined') complete = easing; easing = 'swing'; } $(this).css({ opacity: 1 }).animate({ opacity: 0 }, speed, easing, function() { $(this).css('display', 'none'); // complete callback complete && typeof(complete) === 'function' && complete(); }); return this; }, fadeToggle: function(speed, easing, complete) { return this.each(function() { var el = $(this); el[(el.css('opacity') === 0 || el.css('display') === 'none') ? 'fadeIn' : 'fadeOut'](speed, easing, complete) }) } }) })(Zepto);
animate.js:
(function($, undefined) { var prefix = '', eventPrefix, vendors = { Webkit: 'webkit', Moz: '', O: 'o' }, testEl = document.createElement('div'), supportedTransforms = /^((translate|rotate|scale)(X|Y|Z|3d)?|matrix(3d)?|perspective|skew(X|Y)?)$/i, transform, transitionProperty, transitionDuration, transitionTiming, transitionDelay, animationName, animationDuration, animationTiming, animationDelay, cssReset = {} function dasherize(str) { return str.replace(/([A-Z])/g, '-$1').toLowerCase() } function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() } if(testEl.style.transform === undefined) $.each(vendors, function(vendor, event) { if(testEl.style[vendor + 'TransitionProperty'] !== undefined) { prefix = '-' + vendor.toLowerCase() + '-' eventPrefix = event return false } }) transform = prefix + 'transform' cssReset[transitionProperty = prefix + 'transition-property'] = cssReset[transitionDuration = prefix + 'transition-duration'] = cssReset[transitionDelay = prefix + 'transition-delay'] = cssReset[transitionTiming = prefix + 'transition-timing-function'] = cssReset[animationName = prefix + 'animation-name'] = cssReset[animationDuration = prefix + 'animation-duration'] = cssReset[animationDelay = prefix + 'animation-delay'] = cssReset[animationTiming = prefix + 'animation-timing-function'] = '' $.fx = { off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined), speeds: { _default: 400, fast: 200, slow: 600 }, cssPrefix: prefix, transitionEnd: normalizeEvent('TransitionEnd'), animationEnd: normalizeEvent('AnimationEnd') } $.fn.animate = function(properties, duration, ease, callback, delay) { if($.isFunction(duration)) callback = duration, ease = undefined, duration = undefined if($.isFunction(ease)) callback = ease, ease = undefined if($.isPlainObject(duration)) ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.duration if(duration) duration = (typeof duration == 'number' ? duration : ($.fx.speeds[duration] || $.fx.speeds._default)) / 1000 if(delay) delay = parseFloat(delay) / 1000 return this.anim(properties, duration, ease, callback, delay) } $.fn.anim = function(properties, duration, ease, callback, delay) { var key, cssValues = {}, cssProperties, transforms = '', that = this, wrappedCallback, endEvent = $.fx.transitionEnd, fired = false if(duration === undefined) duration = $.fx.speeds._default / 1000 if(delay === undefined) delay = 0 if($.fx.off) duration = 0 if(typeof properties == 'string') { // keyframe animation cssValues[animationName] = properties cssValues[animationDuration] = duration + 's' cssValues[animationDelay] = delay + 's' cssValues[animationTiming] = (ease || 'linear') endEvent = $.fx.animationEnd } else { cssProperties = [] // CSS transitions for(key in properties) if(supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') ' else cssValues[key] = properties[key], cssProperties.push(dasherize(key)) if(transforms) cssValues[transform] = transforms, cssProperties.push(transform) if(duration > 0 && typeof properties === 'object') { cssValues[transitionProperty] = cssProperties.join(', ') cssValues[transitionDuration] = duration + 's' cssValues[transitionDelay] = delay + 's' cssValues[transitionTiming] = (ease || 'linear') } } wrappedCallback = function(event) { if(typeof event !== 'undefined') { if(event.target !== event.currentTarget) return // makes sure the event didn't bubble from "below" $(event.target).unbind(endEvent, wrappedCallback) } else $(this).unbind(endEvent, wrappedCallback) // triggered by setTimeout fired = true $(this).css(cssReset) callback && callback.call(this) } if(duration > 0) { this.bind(endEvent, wrappedCallback) // transitionEnd is not always firing on older Android phones // so make sure it gets fired setTimeout(function() { if(fired) return wrappedCallback.call(that) }, ((duration + delay) * 1000) + 25) } // trigger page reflow so new elements can animate this.size() && this.get(0).clientLeft this.css(cssValues) if(duration <= 0) setTimeout(function() { that.each(function() { wrappedCallback.call(this) }) }, 0) return this } testEl = null })(Zepto);