Zepto源码分析-动画(fx fx_method)模块
源码注释
// Zepto.js
// (c) 2010-2015 Thomas Fuchs
// Zepto.js may be freely distributed under the MIT license. ;(function($, undefined){
var prefix = '', eventPrefix, // prefix浏览器前缀 -webkit等,eventPrefix事件前缀
vendors = { Webkit: 'webkit', Moz: '', O: 'o' }, //前缀数据源 不包含IE
testEl = document.createElement('div'), //临时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 = {} //将驼峰字符串转成css属性,如aB-->a-b
function dasherize(str) { return str.replace(/([a-z])([A-Z])/, '$1-$2').toLowerCase() }
//修正事件名
function normalizeEvent(name) { return eventPrefix ? eventPrefix + name : name.toLowerCase() } /**
* 根据浏览器内核,设置CSS前缀,事件前缀
* 如-webkit, css:-webkit- event:webkit
* 这里会在vendors存储webkit,moz,o三种前缀
*/
$.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'] = '' /**
* 动画常量数据源
* @type {{off: boolean, speeds: {_default: number, fast: number, slow: number}, cssPrefix: string, transitionEnd: *, animationEnd: *}}
*/
$.fx = {
off: (eventPrefix === undefined && testEl.style.transitionProperty === undefined), //能力检测是否支持动画,具体检测是否支持过渡,支持过渡事件
speeds: { _default: , fast: , slow: },
cssPrefix: prefix, //css 前缀 如-webkit-
transitionEnd: normalizeEvent('TransitionEnd'), //过渡结束事件
animationEnd: normalizeEvent('AnimationEnd') //动画播放结束事件
} /**
* 创建自定义动画
* @param properties 样式集
* @param duration 持续事件
* @param ease 速率
* @param callback 完成时的回调
* @param delay 动画延迟
* @returns {*}
*/
$.fn.animate = function(properties, duration, ease, callback, delay){
//参数修正,传参为function(properties,callback)
if ($.isFunction(duration))
callback = duration, ease = undefined, duration = undefined
if ($.isFunction(ease)) //传参为function(properties,duration,callback)
callback = ease, ease = undefined
if ($.isPlainObject(duration)) //传参为function(properties,{})
ease = duration.easing, callback = duration.complete, delay = duration.delay, duration = duration.duration
// duration 数字:持续时间 字符串:取speeds: { _default: 400, fast: 200, slow: 600 }对应数字
if (duration) duration = (typeof duration == 'number' ? duration :
($.fx.speeds[duration] || $.fx.speeds._default)) / //动画持续时间默认值
if (delay) delay = parseFloat(delay) / //延迟时间,除以1000转换成s
return this.anim(properties, duration, ease, callback, delay)
} /**
* 动画核心方法
* @param properties 样式集
* @param duration 持续事件
* @param ease 速率
* @param callback 完成时的回调
* @param delay 动画延迟
* @returns {*}
*/
$.fn.anim = function(properties, duration, ease, callback, delay){
var key, cssValues = {}, cssProperties, transforms = '', // transforms 变形 cssValues设置给DOM的样式
that = this, wrappedCallback, endEvent = $.fx.transitionEnd,
fired = false //修正持续时间
if (duration === undefined) duration = $.fx.speeds._default /
if (delay === undefined) delay = //如果浏览器不支持动画,持续时间设为0,直接跳动画结束
if ($.fx.off) duration = // properties是动画名
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 { //properties 是样式集
cssProperties = []
// CSS transitions
for (key in properties)
//supportedTransforms.test(key) 正则检测是否为变形
//key + '(' + properties[key] + ') ' 拼凑成变形方法
if (supportedTransforms.test(key)) transforms += key + '(' + properties[key] + ') '
else cssValues[key] = properties[key], cssProperties.push(dasherize(key)) //变形统一存入 cssValues cssProperties
if (transforms) cssValues[transform] = transforms, cssProperties.push(transform) // duration > 0可以播放动画,且properties是对象,表明为过渡,上面有字符串,则为animate
if (duration > && 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 > ){
//绑定动画结束事件
this.bind(endEvent, wrappedCallback)
// transitionEnd is not always firing on older Android phones
// so make sure it gets fired //延时ms后执行动画,注意这里加了25ms,保持endEvent,动画先执行完。
//绑定过事件还做延时处理,是transitionEnd在older Android phones不一定触发
setTimeout(function(){
//如果触发过,就不处理
if (fired) return
wrappedCallback.call(that)
}, ((duration + delay) * ) + )
} // trigger page reflow so new elements can animate
//主动触发页面回流,刷新DOM,让接下来设置的动画可以正确播放
//更改 offsetTop、offsetLeft、 offsetWidth、offsetHeight;scrollTop、scrollLeft、scrollWidth、scrollHeight;clientTop、clientLeft、clientWidth、clientHeight;getComputedStyle() 、currentStyle()。这些都会触发回流。回流导致DOM重新渲染,平时要尽可能避免,但这里,为了动画即时生效播放,则主动触发回流,刷新DOM。
this.size() && this.get().clientLeft //设置样式,启动动画
this.css(cssValues) // duration为0,即浏览器不支持动画的情况,直接执行动画结束,执行回调。
if (duration <= ) setTimeout(function() {
that.each(function(){ wrappedCallback.call(this) })
}, ) return this
} testEl = null //去掉不必要的数据存储,便于垃圾回收
})(Zepto)
// Zepto.js
// (c) 2010-2015 Thomas Fuchs
// Zepto.js may be freely distributed under the MIT license. ;(function($, undefined){
var document = window.document, docElem = document.documentElement,
origShow = $.fn.show, origHide = $.fn.hide, origToggle = $.fn.toggle// origShow展示 origHide隐藏 origToggle展示隐藏开关 /**
* 便捷动画的核心方法
* @param el DOM
* @param speed 持续时间
* @param opacity 不透明度
* @param scale 缩放
* @param callback 回调
* @returns {*}
*/
function anim(el, speed, opacity, scale, callback) {
//修正参数 anim(el,callback)
if (typeof speed == 'function' && !callback) callback = speed, speed = undefined
var props = { opacity: opacity }
if (scale) {
props.scale = scale
el.css($.fx.cssPrefix + 'transform-origin', '0 0') //设置变形原点
}
return el.animate(props, speed, null, callback)//不支持速率变化,
} /**
* 底层方法:隐藏显示的元素
* @param el
* @param speed
* @param scale
* @param callback
* @returns {*}
*/
function hide(el, speed, scale, callback) {
//不透明度设为0,即完全透明,相当于隐藏元素。这里的原理是播放不透明-透明的过渡。
//具体代码为 $(dom).animate({opacity: 0, '-webkit-transform-origin': '0px 0px 0px', '-webkit-transform': 'scale(0, 0)' },800)
//设置了变形原点,缩放为0,它就会缩到左上角再透明
return anim(el, speed, , scale, function(){
origHide.call($(this)) //调用隐藏
callback && callback.call(this)
})
} /**
* 显示
* @param speed 持续时间
* @param callback 回调函数
* @returns {*}
*/
$.fn.show = function(speed, callback) {
origShow.call(this)
//具体代码为 $(dom).animate({opacity: 1, '-webkit-transform-origin': '0px 0px 0px', '-webkit-transform': 'scale(1, 1)' },800)
//设置了变形原点,缩放为0,它就会缩到左上角再透明
if (speed === undefined) speed =
else this.css('opacity', )
return anim(this, speed, , '1,1', callback)
} /**
* 隐藏
* @param speed 持续时间
* @param callback 回调函数
* @returns {*}
*/
$.fn.hide = function(speed, callback) {
if (speed === undefined) return origHide.call(this)
else return hide(this, speed, '0,0', callback)
} /**
* 显示、隐藏开关
* @param speed 持续时间
* @param callback 回调函数
* @returns {*}
*/
$.fn.toggle = function(speed, callback) {
if (speed === undefined || typeof speed == 'boolean')
return origToggle.call(this, speed)
else return this.each(function(){
var el = $(this)
el[el.css('display') == 'none' ? 'show' : 'hide'](speed, callback)
})
} /**
* 淡入淡出
* 原理: $(dom).animate({opacity: 1/0, '-webkit-transform-origin': '0px 0px 0px'},800)
* @param speed 持续时间
* @param opacity 不透明度
* @param callback 回调函数
* @returns {*}
*/
$.fn.fadeTo = function(speed, opacity, callback) {
return anim(this, speed, opacity, null, callback)
} /**
* 淡入
* 原理: $(dom).animate({opacity: 1, '-webkit-transform-origin': '0px 0px 0px'},800)
* @param speed 持续时间
* @param callback 回调函数
* @returns {*}
*/
$.fn.fadeIn = function(speed, callback) {
var target = this.css('opacity')
if (target > ) this.css('opacity', )
else target =
return origShow.call(this).fadeTo(speed, target, callback)
} /**
* 淡出
* 原理: $(dom).animate({opacity: 0, '-webkit-transform-origin': '0px 0px 0px'},800)
* @param speed 持续时间
* @param callback 回调函数
* @returns {*}
*/
$.fn.fadeOut = function(speed, callback) {
return hide(this, speed, null, callback)
} /**
* 淡入淡出开关
* @param speed 持续时间
* @param callback 回调函数
* @returns {*}
*/
$.fn.fadeToggle = function(speed, callback) {
return this.each(function(){
var el = $(this)
el[
(el.css('opacity') == || el.css('display') == 'none') ? 'fadeIn' : 'fadeOut'
](speed, callback)
})
} })(Zepto)
方法图
Zepto源码分析-动画(fx fx_method)模块的更多相关文章
- zepto源码分析系列
如果你也开发移动端web,如果你也用zepto,应该值得你看看.有问题请留言. Zepto源码分析-架构 Zepto源码分析-zepto(DOM)模块 Zepto源码分析-callbacks模块 Ze ...
- 一个普通的 Zepto 源码分析(二) - ajax 模块
一个普通的 Zepto 源码分析(二) - ajax 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块,以 ...
- 一个普通的 Zepto 源码分析(三) - event 模块
一个普通的 Zepto 源码分析(三) - event 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核心模块, ...
- 一个普通的 Zepto 源码分析(一) - ie 与 form 模块
一个普通的 Zepto 源码分析(一) - ie 与 form 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核 ...
- jQuery 源码分析(十) 数据缓存模块 data详解
jQuery的数据缓存模块以一种安全的方式为DOM元素附加任意类型的数据,避免了在JavaScript对象和DOM元素之间出现循环引用,以及由此而导致的内存泄漏. 数据缓存模块为DOM元素和JavaS ...
- jQuery1.9.1源码分析--数据缓存Data模块
jQuery1.9.1源码分析--数据缓存Data模块 阅读目录 jQuery API中Data的基本使用方法介绍 jQuery.acceptData(elem)源码分析 jQuery.data(el ...
- Zepto源码分析(一)核心代码分析
本文只分析核心的部分代码,并且在这部分代码有删减,但是不影响代码的正常运行. 目录 * 用闭包封装Zepto * 开始处理细节 * 正式处理数据(获取选择器选择的DOM) * 正式处理数据(添加DOM ...
- Zepto源码分析(二)奇淫技巧总结
Zepto源码分析(一)核心代码分析 Zepto源码分析(二)奇淫技巧总结 目录 * 前言 * 短路操作符 * 参数重载(参数个数重载) * 参数重载(参数类型重载) * CSS操作 * 获取属性值的 ...
- Hadoop2源码分析-HDFS核心模块分析
1.概述 这篇博客接着<Hadoop2源码分析-RPC机制初识>来讲述,前面我们对MapReduce.序列化.RPC进行了分析和探索,对Hadoop V2的这些模块都有了大致的了解,通过对 ...
随机推荐
- 原生态JS实现banner图的常用所有功能
虽然,用jQuery实现banner图的各种效果十分简单快捷,但是我今天用css+js代码实现了几个banner图的常用功能,效果还不错. 此次,主要想实现以下功能: 1. banner图循环不间断切 ...
- 4 安装MPush
cnblogs-DOC 1.服务器环境 2.安装Redis3.安装Zookeeper4.安装MPush5.安装Alloc服务6.完整测试7.常见问题 一.Linux安装Mpush [root@loca ...
- 数列分段Section II
洛谷传送门 输入时处理出最小的答案和最大的答案,然后二分答案即可. 其余细节看代码 #include <iostream> #include <cstdio> using na ...
- 2.Ubuntu16.04安装QT5.8.0
VSCode编辑器开发CPP:http://www.cnblogs.com/dotnetcrazy/p/6661921.html 下载QT run文件(安装包),一般都是这两个下载的比较多,我这边使用 ...
- 事件驱动的简明讲解(python实现)
关键词:编程范式,事件驱动,回调函数,观察者模式 作者:码匠信龙 举个简单的例子: 有些人喜欢的某个公众号,然后去关注这个公众号,哪天这个公众号发布了篇新的文章,没多久订阅者就会在微信里收到这个公众号 ...
- Azure IoT 技术研究系列4-Azure IoT Hub的配额及缩放级别
上两篇博文中,我们介绍了将设备注册到Azure IoT Hub,设备到云.云到设备之间的通信: Azure IoT 技术研究系列2-设备注册到Azure IoT Hub Azure IoT 技术研究系 ...
- 大数据及hadoop相关知识介绍
一.大数据的基本概念 1.1什么是大数据 互联网企业是最早收集大数据的行业,最典型的代表就是Google和百度,这两个公司是做搜索引擎的,数量都非常庞大,每天都要去把互联网上的各种各样的网页信息抓取下 ...
- cannot locate symbol "atof" referenced by错误分析
ndk从r8升级到r10后, 使用eclipse编译出来的so库报错了,加载库的时候报错cannot locate symbol "atof" referenced by 原因:A ...
- 开始使用gentoo linux——gentoo安装笔记(下)
gentoo安装笔记(下) 上一章,已经对操作系统安装做了充分准备,并且已经从livecd(u盘系统)切换进入了gentoo安装环境中. 不过现在才是真正的开始!打起精神!这可不是在装ubuntu! ...
- swoole使用 常用案例
swoole使用 服务器及客户端 4种服务器[tcp/udp/web/websocket] TCP服务器 //创建Server对象,监听 127.0.0.1:9501端口 $serv = new sw ...