transitionend animationend 事件兼容问题

18 篇文章 0 订阅

      平时在做动画的时候,如果涉及交互比较多一些的时候。比如像拆礼盒,摇筛子等基于微信的小游戏,transitionend和animationend这个两个事件都会用到,之前做微信的小游戏过程中,把两个事件在pc端和移动端的常用的浏览器给测试了一下并做了整理,虽然浏览器的支持结果大同小异,但是还是有一些细微的差别的,其中微信和qq浏览器(其实是同一个)对于两个事件都需要加前缀!

一、transitionend事件

       1.浏览器支持情况

01

      注:transitionend的事件只有三种形式,之所以不检测MozTransitionEndmsTransitionEnd 这两个的事件,因为火狐和IE都已经支持了transitionend,相反的对于加前缀反而不执行事件,oTransitionEnd  代表的是欧朋浏览器,transitionend 一定要小写 否则浏览器不识别,webkitTransitionEnd中T和E是一定要大写的,w大小写是无所谓的!

       2.transitionend有过渡效果的css属性

      为什么要知道有过渡css属性的呢?首先是,实例运用中,经常会发现,一个元素起始时的display:none,想通过transition来实现动画过渡效果,结果发现不行,因为display没有过渡效果! 其次,有过渡的css属性决定了transtionend的执行次数(下面会说),在transitionDuration的时间不为0的时候,有过渡效果的css属性,也就transition-property支持的css的属性有:

02

      3.transitionend事件的多次执行

     transitionend事件执行了几次是取决于transition-property的设置,假设我们设置transitionProperty="width,height,background-color,transform",那么这个时候你应该猜测得到transitionend执行了4次(如果某个属性没有改变值,那么是不会触发transitionend的事件),尝试运行下面的代码就知道:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0"/>
	<title>transitionend - 蜗牛博客(wnworld.com)</title>
	<link rel="stylesheet" type="text/css" href="http://wnworld.com/wp-content/themes/temp1/css/reset.css">
</head>
<body>
	<style type="text/css">
		.movebox{
			width:50px;
			height:50px;
			position: relative;
			background:#f60;
			-webkit-transition-duration: 1s;
			-o-transition-duration: 1s;
			transition-duration: 1s;
			-webkit-transition-timing-function: linear;
			-o-transition-timing-function: linear;
			transition-timing-function: linear;
		}
	</style>


		
	<div class="movebox" id="J_movebox"></div>
	<div class="handguide-btn fixed align-c ">
		<a href="javascript:void(0)" class="wn-btn wn-btn-success" id="J_movingbtn">&nbsp;&nbsp;运动&nbsp;&nbsp; </a> 
		<a href="javascript:void(0)" class="wn-btn wn-btn-success" id="J_returnbeginbtn">&nbsp;&nbsp;恢复&nbsp;&nbsp; </a> 
	</div>
	<script type="text/javascript">
			var movebox=document.getElementById("J_movebox"),
				btn=document.getElementById("J_movingbtn"),
				returnbeginbtn=document.getElementById("J_returnbeginbtn"),
				i=0,
				transition="transition",
				body=document.body || document.documentElement,
				style=body.style;
			var	transitionEnd=(function(){
					var transEndEventNames = {
				      WebkitTransition : 'webkitTransitionEnd',
				      MozTransition    : 'transitionend',
				      OTransition      : 'oTransitionEnd otransitionend',
				      transition       : 'transitionend'
				    }
					for(var name in transEndEventNames){
						if(typeof style[name] === "string"){
							return transEndEventNames[name]
						}
					}
				})();


			var vendorPrefix=(function(){
					var i=0, vendor=["Moz", "Webkit", "Khtml", "O", "ms"];
					transition=transition.charAt(0).toUpperCase() + transition.substr(1);   
					while (i < vendor.length) {
						if (typeof style[vendor[i] + transition] === "string") {
						  return vendor[i];
						}
						i++;
					}
					return false;
				})();


			movebox.addEventListener(transitionEnd,function(){
				i++;
				alert("第"+i+"次执行"+transitionEnd+"事件!")
			},false)
			btn.οnclick=function(){
                                i=0;
				movebox.style.width="150px";
				movebox.style.height="150px";
				movebox.style.backgroundColor="#000";
				movebox.style[vendorPrefix+"Transform"]="translate(100px,100px) rotate(45deg)";
				movebox.style[vendorPrefix+"TransitionProperty"]="width,height,background-color,transform";
			}
			returnbeginbtn.οnclick=function(){
				i=0;
				movebox.style.width="50px";
				movebox.style.height="50px";
				movebox.style.backgroundColor="#f60";
				movebox.style[vendorPrefix+"Transform"]="translate(0px,0px) rotate(0deg)";
				movebox.style[vendorPrefix+"TransitionProperty"]="width,height,background-color,transform";
			}
	</script>
</body>
</html>

      结果很明显:transitionend触发了四次,因为width,height,background-color,transform四个属性都被改变了!而在实际的运用中,我们往往只需要所有的动画结束后执行一次transitionend的事件来达做我们想要做的事情,这个时候就需要我们做一些处理,让transitionend事件在多个css属性改变的情况下执行一次,现在定义一个函数handleTransitionEndEvent来处理多次触发的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var handleTransitionEndEvent= function (elem,fn,duration){
     var called= false ;
     //在每次transitionEnd的事件后执行该函数
     var callback = function (){
             if (!called){
                 fn();
                 called= true ;
            
     };
     elem.addEventListener(transitionEnd, function (){
         callback();
         //通过setTimeout来补救windowphone中不触发事件的问题
         setTimeout(callback,duration);
     }, false );      
};

      通过这个函数函数,就可以解决了transitioned事件多次执行的问题,达到我们想要的目的,这时候把这段函数加到上面的代码中(为了配合本示例,将called的变量放到函数外面),运行下面的代码:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0"/>
	<title>transitionend - 蜗牛博客(wnworld.com)</title>
	<link rel="stylesheet" type="text/css" href="http://wnworld.com/wp-content/themes/temp1/css/reset.css">
</head>
<body>
	<style type="text/css">
		.movebox{
			width:50px;
			height:50px;
			position: relative;
			background:#f60;
			-webkit-transition-duration: 1s;
			-o-transition-duration: 1s;
			transition-duration: 1s;
			-webkit-transition-timing-function: linear;
			-o-transition-timing-function: linear;
			transition-timing-function: linear;
		}
	</style>


		
	<div class="movebox" id="J_movebox"></div>
	<div class="handguide-btn fixed align-c ">
		<a href="javascript:void(0)" class="wn-btn wn-btn-success" id="J_movingbtn">&nbsp;&nbsp;运动&nbsp;&nbsp; </a> 
		<a href="javascript:void(0)" class="wn-btn wn-btn-success" id="J_returnbeginbtn">&nbsp;&nbsp;恢复&nbsp;&nbsp; </a> 
	</div>
	<script type="text/javascript">
			var movebox=document.getElementById("J_movebox"),
				btn=document.getElementById("J_movingbtn"),
				returnbeginbtn=document.getElementById("J_returnbeginbtn"),
				i=0,
				transition="transition",
				body=document.body || document.documentElement,
				style=body.style;
			var	transitionEnd=(function(){
					var transEndEventNames = {
				      WebkitTransition : 'webkitTransitionEnd',
				      MozTransition    : 'transitionend',
				      OTransition      : 'oTransitionEnd otransitionend',
				      transition       : 'transitionend'
				    }
					for(var name in transEndEventNames){
						if(typeof style[name] === "string"){
							return transEndEventNames[name]
						}
					}
				})();


			var vendorPrefix=(function(){
					var i=0, vendor=["Moz", "Webkit", "Khtml", "O", "ms"];
					transition=transition.charAt(0).toUpperCase() + transition.substr(1);   
					while (i < vendor.length) {
						if (typeof style[vendor[i] + transition] === "string") {
						  return vendor[i];
						}
						i++;
					}
					return false;
				})();


			var called=false;
			var handleTransitionEndEvent=function(elem,fn,duration){	
				//在每次transitionEnd的事件后执行该函数
				var callback = function(){
						if (!called){
							fn();
							called=true;
						}
				};
				elem.addEventListener(transitionEnd,function(){
					callback();
					setTimeout(callback,duration);
				},false);
			};
			function transitionEndFn(){
			 	i++;
				alert("执行了"+transitionEnd+"事件"+i+"次");
			};
			handleTransitionEndEvent(movebox,transitionEndFn,"1s");
			btn.οnclick=function(){
				i=0;
				called=false;
				movebox.style.width="150px";
				movebox.style.height="150px";
				movebox.style.backgroundColor="#000";
				movebox.style[vendorPrefix+"Transform"]="translate(100px,100px) rotate(45deg)";
				movebox.style[vendorPrefix+"TransitionProperty"]="width,height,background-color,transform";
			}
			returnbeginbtn.οnclick=function(){
				i=0;
				called=false;
				movebox.style.width="50px";
				movebox.style.height="50px";
				movebox.style.backgroundColor="#f60";
				movebox.style[vendorPrefix+"Transform"]="translate(0px,0px) rotate(0deg)";
				movebox.style[vendorPrefix+"TransitionProperty"]="width,height,background-color,transform";
			}
	</script>
</body>
</html>

      结果每次效果过渡完后,只执行了一次transtionend的事件!关于transitonend的jquery的处理方式,可以参考Bootstrap中的transition.js的处理方式。

二、animationend事件

      1.animationend浏览器支持情况:

03

      animationend的事件只有两种形式:animationend和WebkitAnimationEnd(注意事件名称的大小写)

      2.animationend事件执行次数:

      不同于transitionend事件,animationend只会在动画完成后执行一次:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0"/>
	<title>动画</title>
	<link rel="stylesheet" type="text/css" href="http://wnworld.com/wp-content/themes/temp1/css/reset.css">
	<script src="http://libs.baidu.com/jquery/1.10.0/jquery.js"></script>
	<script type="text/javascript" src="plugin.js"></script>
	<style type="text/css">
		.movebox{
			width:100px;
			height:100px;
			border:1px solid #5d5d5d;
			background: #f60;
			overflow:hidden;
			margin:10px;
			-webkit-animation-duration:1s ;
			-o-animation-duration:1s ;
			animation-duration:1s ;
		}
		@keyframes mymove{
			0%{
				-webkit-transform: translate(0px,0px);
				-moz-transform: translate(0px,0px);
				-ms-transform: translate(0px,0px);
				transform: translate(0px,0px);
			}
			100%{
				-webkit-transform: translate(100px,100px);
				-moz-transform: translate(100px,100px);
				-ms-transform: translate(100px,100px);
				transform: translate(100px,100px);
			}
		}
		@-webkit-keyframes mymove{
			0%{
				-webkit-transform: translate(0px,0px);
				-moz-transform: translate(0px,0px);
				-ms-transform: translate(0px,0px);
				transform: translate(0px,0px);
			}
			100%{
				-webkit-transform: translate(100px,100px);
				-moz-transform: translate(100px,100px);
				-ms-transform: translate(100px,100px);
				transform: translate(100px,100px);
			}
		}
	</style>
</head>
<body>
	<div class="movebox" id="J_movebox"></div>
	<div class="handguide-btn fixed align-c ">
		<a href="javascript:void(0)" class="wn-btn wn-btn-success" id="J_movingbtn">&nbsp;&nbsp;运动&nbsp;&nbsp; </a> 
	</div>
	<script type="text/javascript">
		var movebox=document.getElementById("J_movebox"),
			btn=document.getElementById("J_movingbtn"),
			transition="transition",
			body=document.body || document.documentElement,
			style=body.style;
		var vendorPrefix=(function(){
					var i=0, vendor=["Moz", "Webkit", "Khtml", "O", "ms"];
					transition=transition.charAt(0).toUpperCase() + transition.substr(1);   
					while (i < vendor.length) {
						if (typeof style[vendor[i] + transition] === "string") {
						  return vendor[i];
						}
						i++;
					}
					return false;
			})();
		var animationEnd=(function(){
			if(vendorPrefix=="Webkit"){
				return "webkitAnimationEnd";
			}else{
				return "animationend";
			}
		}());
		movebox.addEventListener(animationEnd,function(){
			alert("执行了"+animationEnd+"事件!");
			movebox.style[vendorPrefix+"AnimationName"]="";
		},false)
		btn.οnclick=function(){
			movebox.style[vendorPrefix+"AnimationName"]="mymove";
		}
	</script>
</body>
</html>

理解transtionend和animationend两个事件,主要是在浏览器的前缀上面,搞清楚了这东西,做起来就比较得心应手了!

转载于http://wnworld.com/archives/191.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值