原生js判断css3动画过度(transition)结束 transitionend事件 以及关键帧keyframes动画结束(animation)回调函数 animationEnd 以及 css 过渡 transition无效
上图的 demo 主要讲的 是 css transition的过渡回调函数transitionend事件;
css3 的时代,css3--动画 一切皆有可能;
传统的js 可以通过回调函数判断动画是否结束;即使是采用CSS技术生成动画效果,JavaScript仍然能捕获动画或变换的结束事件;
transitionend
事件和animationend
事件标准的浏览器事件,但在WebKit浏览器里你仍然需要使用webkit
前缀,所以,我们不得不根据各种浏览器分别检测事件
var transitions = {
'transition':'transitionend',
'OTransition':'oTransitionEnd',
'MozTransition':'transitionend',
'WebkitTransition':'webkitTransitionEnd'
}
下面附上源代码:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>suface js判断css动画是否结束</title>
</head> <body> <p>一旦动画或变换结束,回调函数就会触发。不再需要大型类库支持。<br> </p>
<style type="text/css">
.sample {
width: 200px;
height: 200px;
border: 1px solid green;
background: lightgreen;
opacity: 1;
margin-bottom: 20px;
transition-property: opacity;
/*transition-duration: .5s;*/
transition-duration:3s;
}
.sample.hide {
opacity: 0;
}
</style>
<div class="sample">css3动画过度慢慢隐藏(transition-duration:3s;)</div>
<p><button onclick="this.style.display='none';startFade();">慢慢消退,检测结束事件</button></p>
<script>
;(function() {
var e = document.getElementsByClassName('sample')[0];
function whichTransitionEvent(){
var t,
el = document.createElement('surface'),
transitions = {
'transition':'transitionend',
'OTransition':'oTransitionEnd',
'MozTransition':'transitionend',
'WebkitTransition':'webkitTransitionEnd'
} for(t in transitions){
if( el.style[t] !== undefined ){
return transitions[t];
}
}
} var transitionEvent = whichTransitionEvent();
transitionEvent && e.addEventListener(transitionEvent, function() {
alert('css3运动结束!我是回调函数,没有使用第三方类库!');
e. removeEventListener(transitionEvent,arguments.callee,false);//销毁事件 }); startFade = function() {
e.className+= ' hide';
}
})();
</script>
</body>
</html> //兼容性 详情
另外,注意一下:在js调用中;transitionend 存几个个问题:
如果 transition 中:变换的属性有多个 ;比如设置宽高 过度(transition :width:.2s,height:.2s), transitionend 事件会促发2次
<style>
.surfaces_box{ background:url(../../loveImg/QioA-fxehfqi8208393.jpg) no-repeat center center;;width:550px;;height:343px;; margin:0 auto; position: relative;}
.surfaces_box p{ position:absolute; bottom:0; left:0; right:0; color:#333; text-align:center; padding:10px 0; background: rgba(255,255,255,.4) }
.surfaces{width:100px;height:100px;background:red; color:#fff; text-align:center; transition:width 1s ,height 1s;} </style> <div class="surfaces_box">
<div class="surfaces" id="j_surfaces">click me </div>
<p>http://www.cnblogs.com/surfaces/</p>
</div>
<script>
function addEnd(obj,fn){
obj.addEventListener('WebkitTransitionEnd',fn,false);
obj.addEventListener('transitionend',fn,false);
} var surfaces=document.getElementById("j_surfaces");
surfaces.onclick=function(){
this.style.width=this.offsetWidth+100+"px";
this.style.height=this.offsetHeight+100+"px";
}; addEnd(surfaces,function(){
alert('CSS3 过渡结束回调 ');
}); </script>
如果 transition 中:变换的属性 (transition :width:.1s);transitionend 之后再次改变 宽度; 再次促发 transition类似递归;
<style>
.surfaces_box{ background:url(../../loveImg/QioA-fxehfqi8208393.jpg) no-repeat center center;;width:550px;;height:343px;; margin:0 auto; position: relative;}
.surfaces_box p{ position:absolute; bottom:0; left:0; right:0; color:#333; text-align:center; padding:10px 0; background: rgba(255,255,255,.4) }
.surfaces{width:100px;height:100px;background:red; color:#fff; text-align:center; transition:width 1s} </style> <div class="surfaces_box">
<div class="surfaces" id="j_surfaces">click me </div>
<p>http://www.cnblogs.com/surfaces/</p>
</div>
<script>
function addEnd(obj,fn){
obj.addEventListener('WebkitTransitionEnd',fn,false);
obj.addEventListener('transitionend',fn,false);
} var surfaces=document.getElementById("j_surfaces");
surfaces.onclick=function(){
this.style.width=this.offsetWidth+100+"px";
}; addEnd(surfaces,function(){
this.style.width=this.offsetWidth+100+"px";
alert('CSS3 过渡结束回调 ');
}); </script>
如果元素原先display:none 到block,transition 过渡无效;可能导致transitionend 失效;举个例子 dom元素从display:none 到block ,dom的opacity从0到1的 transition没过渡 ;
<style>
.surfaces_box{ background:url(../../loveImg/QioA-fxehfqi8208393.jpg) no-repeat center center;;width:550px;;height:343px;; margin:0 auto; position: relative;}
.surfaces_box p{ position:absolute; bottom:0; left:0; right:0; color:#333; text-align:center; padding:10px 0; background: rgba(255,255,255,.4) }
.surfaces{width:100px;height:100px;background:red; color:#fff; text-align:center; transition:width 1s}
.surfaces_box .hideElement{width:100px;height:100px; position:absolute; right:0; top:0; background:red; color:#fff; text-align:center; transition:opacity 1s; display:none; opacity:0;}
</style> <div class="surfaces_box">
<div class="surfaces" id="j_surfaces">click me </div> <div class="hideElement" id="j_hideElement">opacity transition</div> <p>http://www.cnblogs.com/surfaces/</p>
</div>
<script> var j_hideElement=document.getElementById("j_hideElement");
var surfaces=document.getElementById("j_surfaces");
surfaces.onclick=function(){
j_hideElement.style.display='block'; //// 原先display=none
j_hideElement.style.opacity=1; // transition:opacity 1s;
}; </script>
上图 dom元素 从none到block,导致 transition-duration 无法渲染;
1 一般是这样解决 加个计时器延迟
2 或者 强制 /强制 获取当前的内联样式
3或者重绘
都是从none到block ,dom元素刚生成未能即使渲染,导致过度失效,所以主动触发页面回流(重绘),刷新DOM;
更改 offsetTop、offsetLeft、 offsetWidth、offsetHeight;scrollTop、scrollLeft、scrollWidth、scrollHeight;clientTop、clientLeft、clientWidth、clientHeight;getComputedStyle() 、currentStyle()。这些都会触发回流。回流导致DOM重新渲染,平时要尽可能避免,但这里,为了动画即时生效播放,则主动触发回流,刷新DOM。
4 另外 部分低端安卓机型或者wp手机 无法促发 transitionend事件 需要主动触发一次
以上综合解决方式大致如下;
var fired = false;
var handler = function () {//回调函数中解绑事件 callback && callback.apply(obj,arguments);
fired=true; obj.removeEventListener(transitionEnd,arguments.callee,false)
}; if(obj.addEventListener){
obj.addEventListener(transitionEnd, handler,false);
} setTimeout(function(){//绑定过事件还做延时处理,是transitionEnd在older Android phones不一定触发
if(fired) return
handler()
},(duration + delay) + 25);
我们进行封装一下;封装后的直接调用如下;参考zepto 改写;不依赖任何类库,详情源码调用例子 点击transform.js 查看;该函数兼容性与zepto一致;
transform(dom元素,{ css属性:css值},transitionDuration(单位:毫秒),transitionTiming,transitionend回调函数,transitionDelay(单位:毫秒));
transform(dom元素,keyframesName,animationDuration,animationTiming,animationend回调函数,animationDelay(单位:毫秒));
参数说明:
/*
* js transfrom.js
* @param obj {obj} 原生dom对象
* @param properties {json} ||string { translate3d:'220px,10px,0',left:'1em',opacity:0.2, rotateY:'30deg'} || animationName 多个可以以逗号分割 如 'fadeIn,sliderDown';
* @param duration {number} 默认400毫秒 可省略
* @param ease {str} 默认linear,可省略 支持 cubic-bezier(0.42,0,1,1)写法;
* @param callback {function} 回调函数 可省略
* @param delay {number} 延迟时间 可省略 */
多种参数 调用写法示例:
/* http://www.cnblogs.com/surfaces * @param properties 为 {} 或者 string ;如果 properties= string 为animation- name * transform(elem, properties)
* transform(elem, properties, ease)
* transform(elem, properties, ease, delay)
* transform(elem, properties, ease, callback, delay)
* transform(elem, properties, callback)
* transform(elem, properties, callback, delay)
* transform(elem, properties, duration )
* transform(elem, properties, duration, ease)
* transform(elem, properties, duration, delay)
* transform(elem, properties, duration, callback)
* transform(elem, properties, duration, callback,delay)
* transform(elem, properties, duration, ease, delay)
* transform(elem, properties, duration, ease, callback)
* transform(elem, properties, duration, ease, callback,delay) //使用示例如下:
transform(elem,{translateX:'150px',left:'1em',opacity:0.2,perspective:'400px', rotateY:'40deg'},600,'linear',
function(){ console.log('transition结束回调') },200) ; transform(elem, keyframesName,600,'linear',function(){ console.log('animation结束回调') },200) ;
*/
不要搞混css3动画事件 webkitAnimationEnd 事件
至于animation关键帧动画结束,提供了3个api;如下
开始事件 webkitAnimationStart
结束事件 webkitAnimationEnd
重复运动事件 webkitAnimationIteration;
本文地址:http://www.cnblogs.com/surfaces/
总结:
相同点:
两者都在移动端大放光彩;利用GPU加速性能,相对流畅;
利用 js进行对动画结束事件可以捕捉监听;
区别之处
transition 只有唯一的事件 transitionend,而animation 有3个;
transition 强调过渡,Transition + Transform = 两个关键帧的Animation
animation 强调流程与控制,Duration + TransformLib + Control = 多个关键帧的Animation
animation 可以实时捕捉操作修改属性, 而transition无法捕捉 中间过程;
transition 往往需要事件驱动,hover,click之类 促发,animation从flash延伸出来
原生js判断css3动画过度(transition)结束 transitionend事件 以及关键帧keyframes动画结束(animation)回调函数 animationEnd 以及 css 过渡 transition无效的更多相关文章
- 原生js判断css动画结束 css 动画结束的回调函数
原文:原生js判断css动画结束 css 动画结束的回调函数 css3 的时代,css3--动画 一切皆有可能: 传统的js 可以通过回调函数判断动画是否结束:即使是采用CSS技术生成动画效果,Jav ...
- 原生js与css3结合的电风扇
最近学习了css3,就琢磨做些东西练练手,下面是自己写的一个电风扇,使用了原生js中的定时器和css3的一些属性 <!doctype html> <html lang="e ...
- 瀑布流的三种实现方式(原生js+jquery+css3)
前言 项目需求要弄个瀑布流的页面,用的是waterfall这个插件,感觉还是可以的,项目赶就没自己的动手写.最近闲来没事,就自己写个.大致思路理清楚,还是挺好实现的... 原生javascript版 ...
- 原生JS判断密码强弱
前些天工作中有这个需求,自己手写了相关的JS代码,第一种方法是通过ASCII 码判断密码类型,完成用户注册时判断用户输入密码的强度,分强.弱.中三等级,它可以根据用户输入的密码显示对应的密码强弱等级, ...
- 深入理解CSS过渡transition
× 目录 [1]定义 [2]过渡属性 [3]持续时间[4]延迟时间[5]时间函数[6]多值[7]阶段[8]触发[9]API 前面的话 通过过渡transition,可以让web前端开发人员不需要jav ...
- css过渡transition属性
一.CSS3 过渡 (一).CSS3过渡简介 CSS3过渡是元素从一种样式逐渐改变为另一种的效果. 实现过渡效果的两个要件: 规定把效果添加到哪个 CSS 属性上 规定效果的时长 定义动画的规则 过渡 ...
- 深入css过渡transition
通过过渡transition,可以让web前端开发人员不需要javascript就可以实现简单的动画交互效果.过渡属性看似简单,但实际上它有很多需要注意的细节和容易混淆的地方. 过渡transitio ...
- UA判断打开页面的环境,然后在callBack写相应环境下的回调函数
这是js代码 /* * 2016.11.10 * SunJingxin * V 1.0.0 * */ (function(){ /* * 使用方法: * 一.引入ua.js * 二.直接调用 Mobi ...
- css过渡transition
定义 过渡transition是一个复合属性,包括transition-property.transition-duration.transition-timing-function.transiti ...
随机推荐
- 为智能硬件提供一站式解决方案——机智云GoKit评测
为智能硬件提供一站式解决方案——机智云GoKit评测 2014年12月24日 作者: ladouyu 3 17,414+ 4 EMW3162GoKit开发板STM32F103智能硬件机智云2.0 从物 ...
- Smarty模板引擎的使用
Smarty模板引擎的使用 Smarty是PHP中一个基于MVC模式的模板引擎. Download: http://www.smarty.net/download 特点 1. 最快速度的程序开发 ...
- 泛泰A850 (高通8064+720p)刷4.4专用中文recovery TWRP2.7.1.3版
欢迎关注泛泰非盈利专业第三方开发团队 VegaDevTeam (本team 由 syhost suky zhaochengw(z大) xuefy(大星星) tenfar(R大师) loogeo cr ...
- 【SSH 基础】浅谈Hibernate关系映射(4)
继上篇博客 多对多关联映射(单向) 多对多对象关系映射,须要增加一张新表完毕基本映射. Hibernate会自己主动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联,多 ...
- Android平台调用Web Service:螺纹的引入
连接文本 剩下的问题 MainActivity的onCreate方法中假设没有有这段代码: // 强制在UI线程中操作 StrictMode.setThreadPolicy(new StrictMod ...
- 《JavaScript设计模式与开发实践》读书笔记之中介者模式
1. 中介者模式 中介者模式的作用就是用来解除对象与对象之间的紧耦合关系,增加中介者后,所有相关对象都通过中介者来通信,而不再相互引用 1.1中介者模式的例子 以泡泡堂游戏为例,先定义一个玩家构造函数 ...
- 21天教你学会C++
- Apache James使用的方法及相关心得(转)
经过一番的辛苦努力,终于把James 配置搞定啦,好记性不如烂笔头啊,赶紧记下我的成功经过,以备以后查阅! 首先要做的就是配置域名的MX 记录啦: 先添加一条A记录: mail.abc.com 指向 ...
- web service接口测试工具选型
1 简介 1.1 范围 1.2 目的 本文档用于指导测试部进行接口测试. 2013-03-11磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.com ...
- 树上点对统计poj1741(树的点分治)
给定一棵树,边上有权值,要统计有多少对点路径的权值和<=k 分治算法在树的路径中的应用 这个论文里面有分析. 任意两点的路径,要么过根结点,要么在子树中.如果在子树中,那么只要递归处理就行了. ...