View Code
var fade = function(element, transparency, speed, callback){……} 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5 <script>
6 function rand(min,max){
7 return Math.round(min+(Math.random()*(max-min)));
8 };
9 //透明度渐变:transparency:透明度 0(全透)-100(不透);speed:速度1-100,默认为1
10 var fade = function(element, transparency, speed, callback){
11 if(typeof(element)=='string')element=document.getElementById(element);
12 if(!element.effect){
13 element.effect = {};
14 element.effect.fade=0;
15 }
16 clearInterval(element.effect.fade);
17 var speed=speed||1;
18 var start=(function(elem){
19 var alpha;
20 if(navigator.userAgent.toLowerCase().indexOf('msie') != -1){
21 alpha=elem.currentStyle.filter.indexOf("opacity=") >= 0?(parseFloat( elem.currentStyle.filter.match(/opacity=([^)]*)/)[1] )) + '':
22 '100';
23 }else{
24 alpha=100*elem.ownerDocument.defaultView.getComputedStyle(elem,null)['opacity'];
25 }
26 return alpha;
27 })(element);
28 if(window.console&&window.console.log)console.log('start: '+start+" end: "+transparency);
29 element.effect.fade = setInterval(function(){
30 start = start < transparency ? Math.min(start + speed, transparency) : Math.max(start - speed, transparency);
31 element.style.opacity = start / 100;
32 element.style.filter = 'alpha(opacity=' + start + ')';
33 if(Math.round(start) == transparency){
34 element.style.opacity = transparency / 100;
35 element.style.filter = 'alpha(opacity=' + transparency + ')';
36 clearInterval(element.effect.fade);
37 if(callback)callback.call(element);
38 }
39 }, 20);
40 };
41 //移动到指定位置,position:移动到指定left及top 格式
42 //{left:120, top:340}或{left:120}或{top:340};speed:速度 1-100,默认为10
43 var move = function(element, position, speed, callback){
44 if(typeof(element)=='string')element=document.getElementById(element);
45 if(!element.effect){
46 element.effect = {};
47 element.effect.move=0;
48 }
49 clearInterval(element.effect.move);
50 var speed=speed||10;
51 var start=(function(elem){
52 var posi = {left:elem.offsetLeft, top:elem.offsetTop};
53 while(elem = elem.offsetParent){
54 posi.left += elem.offsetLeft;
55 posi.top += elem.offsetTop;
56 };
57 return posi;
58 })(element);
59 element.style.position = 'absolute';
60 var style = element.style;
61 var styleArr=[];
62 if(typeof(position.left)=='number')styleArr.push('left');
63 if(typeof(position.top)=='number')styleArr.push('top');
64 element.effect.move = setInterval(function(){
65 for(var i=0;i<styleArr.length;i++){
66 start[styleArr[i]] += (position[styleArr[i]] - start[styleArr[i]]) * speed/100;
67 style[styleArr[i]] = start[styleArr[i]] + 'px';
68 }
69 for(var i=0;i<styleArr.length;i++){
70 if(Math.round(start[styleArr[i]]) == position[styleArr[i]]){
71 if(i!=styleArr.length-1)continue;
72 }else{
73 break;
74 }
75 for(var i=0;i<styleArr.length;i++)style[styleArr[i]] = position[styleArr[i]] + 'px';
76 clearInterval(element.effect.move);
77 if(callback)callback.call(element);
78
79 }
80 }, 20);
81 };
82
83 //长宽渐变:size:要改变到的尺寸 格式 {width:400, height:250}或
84 //{width:400}或{height:250};speed:速度 1-100,默认为10
85 var resize = function(element, size, speed, callback){
86 if(typeof(element)=='string')element=document.getElementById(element);
87 if(!element.effect){
88 element.effect = {};
89 element.effect.resize=0;
90 }
91 clearInterval(element.effect.resize);
92 var speed=speed||10;
93 var start = {width:element.offsetWidth, height:element.offsetHeight};
94 var styleArr=[];
95 if(!(navigator.userAgent.toLowerCase().indexOf('msie') != -1&&document.compatMode == 'BackCompat')){
96 //除了ie下border-content式盒模型情况外,需要对size加以修正
97 var CStyle=document.defaultView?document.defaultView.getComputedStyle(element,null):element.currentStyle;
98 if(typeof(size.width)=='number'){
99 styleArr.push('width');
100 size.width=size.width-CStyle.paddingLeft.replace(/\D/g,'')-CStyle.paddingRight.replace(/\D/g,'');
101 }
102 if(typeof(size.height)=='number'){
103 styleArr.push('height');
104 size.height=size.height-CStyle.paddingTop.replace(/\D/g,'')-CStyle.paddingBottom.replace(/\D/g,'');
105 }
106 }
107 element.style.overflow = 'hidden';
108 var style = element.style;
109 element.effect.resize = setInterval(function(){
110 for(var i=0;i<styleArr.length;i++){
111 start[styleArr[i]] += (size[styleArr[i]] - start[styleArr[i]]) * speed/100;
112 style[styleArr[i]] = start[styleArr[i]] + 'px';
113 }
114 for(var i=0;i<styleArr.length;i++){
115 if(Math.round(start[styleArr[i]]) == size[styleArr[i]]){
116 if(i!=styleArr.length-1)continue;
117 }else{
118 break;
119 }
120 for(var i=0;i<styleArr.length;i++)style[styleArr[i]] = size[styleArr[i]] + 'px';
121 clearInterval(element.effect.resize);
122 if(callback)callback.call(element);
123
124 }
125 }, 20);
126 };
127 </script></head>
128 <body>
129 <div id="testDiv" style="position:absolute; right:100px; top:50px; background-color:#abc; width:100px; height:50px;padding:10px;" onclick="alert(this.style.filter)">
130 <div style="background-color:#369; height:100%;"></div></div>
131 <br/>
132   动画测试  
133
134 <input type="button" value="改变大小"
135 onClick="resize('testDiv', {width:rand(60,600),height:rand(30,300)})" />
136 <input type="button" value="改变宽度"
137 onClick="resize('testDiv', {width:rand(60,600)})" />
138 <input type="button" value="改变高度"
139 onClick="resize('testDiv', {height:rand(30,300)})" />
140  
141 <input type="button" value="移动位置"
142 onClick="move('testDiv', {left:rand(40,600),top:rand(40,400)})" />
143 <input type="button" value="水平移动"
144 onClick="move('testDiv', {left:rand(40,600)})" />
145 <input type="button" value="垂直移动"
146 onClick="move('testDiv', {top:rand(40,400)})" />
147  
148 <input type="button" value="透明度变化"
149 onClick="fade('testDiv', rand(5,100))" />
150  
151 <input type="button" value="还原"
152 onClick="var ele=document.getElementById('testDiv');clearInterval(ele.effect.move);clearInterval(ele.effect.fade);clearInterval(ele.effect.resize);ele.style.cssText='position:absolute; right:100px; top:50px; background-color:#abc; width:100px; height:50px;padding:10px;'" />
153 </body>
154 </html>
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
5 <script>
6 function rand(min,max){
7 return Math.round(min+(Math.random()*(max-min)));
8 };
9 //透明度渐变:transparency:透明度 0(全透)-100(不透);speed:速度1-100,默认为1
10 var fade = function(element, transparency, speed, callback){
11 if(typeof(element)=='string')element=document.getElementById(element);
12 if(!element.effect){
13 element.effect = {};
14 element.effect.fade=0;
15 }
16 clearInterval(element.effect.fade);
17 var speed=speed||1;
18 var start=(function(elem){
19 var alpha;
20 if(navigator.userAgent.toLowerCase().indexOf('msie') != -1){
21 alpha=elem.currentStyle.filter.indexOf("opacity=") >= 0?(parseFloat( elem.currentStyle.filter.match(/opacity=([^)]*)/)[1] )) + '':
22 '100';
23 }else{
24 alpha=100*elem.ownerDocument.defaultView.getComputedStyle(elem,null)['opacity'];
25 }
26 return alpha;
27 })(element);
28 if(window.console&&window.console.log)console.log('start: '+start+" end: "+transparency);
29 element.effect.fade = setInterval(function(){
30 start = start < transparency ? Math.min(start + speed, transparency) : Math.max(start - speed, transparency);
31 element.style.opacity = start / 100;
32 element.style.filter = 'alpha(opacity=' + start + ')';
33 if(Math.round(start) == transparency){
34 element.style.opacity = transparency / 100;
35 element.style.filter = 'alpha(opacity=' + transparency + ')';
36 clearInterval(element.effect.fade);
37 if(callback)callback.call(element);
38 }
39 }, 20);
40 };
41 //移动到指定位置,position:移动到指定left及top 格式
42 //{left:120, top:340}或{left:120}或{top:340};speed:速度 1-100,默认为10
43 var move = function(element, position, speed, callback){
44 if(typeof(element)=='string')element=document.getElementById(element);
45 if(!element.effect){
46 element.effect = {};
47 element.effect.move=0;
48 }
49 clearInterval(element.effect.move);
50 var speed=speed||10;
51 var start=(function(elem){
52 var posi = {left:elem.offsetLeft, top:elem.offsetTop};
53 while(elem = elem.offsetParent){
54 posi.left += elem.offsetLeft;
55 posi.top += elem.offsetTop;
56 };
57 return posi;
58 })(element);
59 element.style.position = 'absolute';
60 var style = element.style;
61 var styleArr=[];
62 if(typeof(position.left)=='number')styleArr.push('left');
63 if(typeof(position.top)=='number')styleArr.push('top');
64 element.effect.move = setInterval(function(){
65 for(var i=0;i<styleArr.length;i++){
66 start[styleArr[i]] += (position[styleArr[i]] - start[styleArr[i]]) * speed/100;
67 style[styleArr[i]] = start[styleArr[i]] + 'px';
68 }
69 for(var i=0;i<styleArr.length;i++){
70 if(Math.round(start[styleArr[i]]) == position[styleArr[i]]){
71 if(i!=styleArr.length-1)continue;
72 }else{
73 break;
74 }
75 for(var i=0;i<styleArr.length;i++)style[styleArr[i]] = position[styleArr[i]] + 'px';
76 clearInterval(element.effect.move);
77 if(callback)callback.call(element);
78
79 }
80 }, 20);
81 };
82
83 //长宽渐变:size:要改变到的尺寸 格式 {width:400, height:250}或
84 //{width:400}或{height:250};speed:速度 1-100,默认为10
85 var resize = function(element, size, speed, callback){
86 if(typeof(element)=='string')element=document.getElementById(element);
87 if(!element.effect){
88 element.effect = {};
89 element.effect.resize=0;
90 }
91 clearInterval(element.effect.resize);
92 var speed=speed||10;
93 var start = {width:element.offsetWidth, height:element.offsetHeight};
94 var styleArr=[];
95 if(!(navigator.userAgent.toLowerCase().indexOf('msie') != -1&&document.compatMode == 'BackCompat')){
96 //除了ie下border-content式盒模型情况外,需要对size加以修正
97 var CStyle=document.defaultView?document.defaultView.getComputedStyle(element,null):element.currentStyle;
98 if(typeof(size.width)=='number'){
99 styleArr.push('width');
100 size.width=size.width-CStyle.paddingLeft.replace(/\D/g,'')-CStyle.paddingRight.replace(/\D/g,'');
101 }
102 if(typeof(size.height)=='number'){
103 styleArr.push('height');
104 size.height=size.height-CStyle.paddingTop.replace(/\D/g,'')-CStyle.paddingBottom.replace(/\D/g,'');
105 }
106 }
107 element.style.overflow = 'hidden';
108 var style = element.style;
109 element.effect.resize = setInterval(function(){
110 for(var i=0;i<styleArr.length;i++){
111 start[styleArr[i]] += (size[styleArr[i]] - start[styleArr[i]]) * speed/100;
112 style[styleArr[i]] = start[styleArr[i]] + 'px';
113 }
114 for(var i=0;i<styleArr.length;i++){
115 if(Math.round(start[styleArr[i]]) == size[styleArr[i]]){
116 if(i!=styleArr.length-1)continue;
117 }else{
118 break;
119 }
120 for(var i=0;i<styleArr.length;i++)style[styleArr[i]] = size[styleArr[i]] + 'px';
121 clearInterval(element.effect.resize);
122 if(callback)callback.call(element);
123
124 }
125 }, 20);
126 };
127 </script></head>
128 <body>
129 <div id="testDiv" style="position:absolute; right:100px; top:50px; background-color:#abc; width:100px; height:50px;padding:10px;" onclick="alert(this.style.filter)">
130 <div style="background-color:#369; height:100%;"></div></div>
131 <br/>
132   动画测试  
133
134 <input type="button" value="改变大小"
135 onClick="resize('testDiv', {width:rand(60,600),height:rand(30,300)})" />
136 <input type="button" value="改变宽度"
137 onClick="resize('testDiv', {width:rand(60,600)})" />
138 <input type="button" value="改变高度"
139 onClick="resize('testDiv', {height:rand(30,300)})" />
140  
141 <input type="button" value="移动位置"
142 onClick="move('testDiv', {left:rand(40,600),top:rand(40,400)})" />
143 <input type="button" value="水平移动"
144 onClick="move('testDiv', {left:rand(40,600)})" />
145 <input type="button" value="垂直移动"
146 onClick="move('testDiv', {top:rand(40,400)})" />
147  
148 <input type="button" value="透明度变化"
149 onClick="fade('testDiv', rand(5,100))" />
150  
151 <input type="button" value="还原"
152 onClick="var ele=document.getElementById('testDiv');clearInterval(ele.effect.move);clearInterval(ele.effect.fade);clearInterval(ele.effect.resize);ele.style.cssText='position:absolute; right:100px; top:50px; background-color:#abc; width:100px; height:50px;padding:10px;'" />
153 </body>
154 </html>
透明度渐变:transparency:透明度 0(全透)-100(不透);speed:速度1-100,默认为1
例<input type="button" value="透明度变化" onClick="fade('testDiv', 40)" />
var move = function(element, position, speed, callback){……}
//移动到指定位置,position:移动到指定left及top 格式{left:120, top:340}或{left:120}或{top:340};speed:速度 1-100,默认为10
例<input type="button" value="垂直移动" onClick="move('testDiv', {top:400})" />
var resize = function(element, size, speed, callback){……}
//长宽渐变:size:要改变到的尺寸 格式 {width:400, height:250}或{width:400}或{height:250};speed:速度 1-100,默认为10
例<input type="button" value="改变高度" onClick="resize('testDiv', {height:300})" />
简单解释一下我的动画函数里几个要点的实现
1、获取一个元素的透明度
如果是IE浏览器,则攻取最终样式的滤镜filter的值,再通过正则表达式获取到透明度滤镜alpha的值,如果不存在透明度滤镜值,则透明度为100。
如果是非IE浏览器,那么可以获取最终样式的opacity属性,
为了简化函数function getOpacity(elem){
var alpha;
if(navigator.userAgent.toLowerCase().indexOf('msie') != -1){
alpha=elem.currentStyle.filter.indexOf("opacity=") >= 0?(parseFloat( elem.currentStyle.filter.match(/opacity=([^)]*)/)[1] )) + '':
'100';
}else{
alpha=100*elem.ownerDocument.defaultView.getComputedStyle(elem,null)['opacity'];
}
return alpha;
};
2、设置透明度
这个就简单了,不用管浏览器,通通的设置opacity及filter,
element.style.opacity = start / 100;
element.style.filter = 'alpha(opacity=' + start + ')';
实际上这儿我偷了个懒,真正无懈可击的写法,应该是判断一下是否IE浏览器,因为在一些情况下可能使用多个滤镜,这时应该用正则替换alpha滤镜的值,而不是直接设置style.filter = 'alpha(opacity=' + start + ')';
3、element.offsetWidth、element.offsetHeight与element.style.width、element.style.height的关系
只有在IE的border-content式盒模型情况下,这两个值才是相等的,即elementoffsetWidth==element.style.width+element.style.paddingLeft+element.style.paddingRight+element.style.borderLeftWidth+element.style.borderRightWidth
而我认为border-content式盒模型是符合修改元素尺寸时的心理预期的,对非border-content式盒模型情况下要作一个尺寸的修正。
在其它情况下应该对该值加以修正
if(!(navigator.userAgent.toLowerCase().indexOf('msie') != -1&&document.compatMode == 'BackCompat')){
//除了ie下border-content式盒模型情况外,需要对size加以修正
var CStyle=document.defaultView?document.defaultView.getComputedStyle(element,null):element.currentStyle;
if(typeof(size.width)=='number'){
size.width=size.width-CStyle.paddingLeft.replace(/\D/g,'')-CStyle.paddingRight.replace(/\D/g,'');
}
if(typeof(size.height)=='number'){
size.height=size.height-CStyle.paddingTop.replace(/\D/g,'')-CStyle.paddingBottom.replace(/\D/g,'');
}
}
有人认为以上的修正中默认了padding值的单位是px并且为整数,是不对的,
实际上经由我在ie及firefox下的测试,引用最终样式的padding值,必然是整数,并以px为单位。
4、关于把三个函数合并成一个通用动画函数
以上三个函数的主要逻辑都是一样的:
通过setInterval每隔一定时间修改元素的style属性,以达到动画效果。
所以,把三个函数合并成一个函数是可以的
只是需要在修改特定的属性时出于兼容性,必须作些处理,
因为不同的属性其值类型及单位不一样,不同浏览器下也有区别
如透明度 在非ie下为小数,在ie下是一个特别的滤镜设置
如颜色 一般是用16进制,并有#号前缀
预计这个通用的动画函数的参数会有点多,接口类下
function animator(element, interval, start, end, style, speed, tmp, callback){……}
说明
function animator(元素或元素ID, 计时器句柄,起始值,目标值,需修改的属性, 步进值(增量),值转换过滤方法(用于修改非普通递增递减形的数据,比如16进制颜色递增、前缀符号后缀单位修正), 回调函数)
运行示例
function animator('testdiv','bgcolor','#336699','#aabbcc','backgroundColor',2,changeColor,callback)
颜色修改方法示例(仅供参考,未测试)
changeColor=function(start,end,speed){
var _10to16 = function(color){
function tmp(index){
var tmp = color[index].toString(16);
return tmp.length == 1 ? "0" + tmp : tmp;
};
return "#" + tmp(0) + tmp(1) + tmp(2);
};
var x16to10 = function(color){
if(!/^#[0-9A-Fa-f]{3,6}$/i.test(color))retun color;
function tmp(index){
return color.charAt(index);
};
color = color.substring(1);
if(color.length == 3)
color = tmp(0) + tmp(0) + tmp(1) + tmp(1) + tmp(2) + tmp(2);
return [parseInt(tmp(0) + tmp(1), 16), parseInt(tmp(2) + tmp(3), 16), parseInt(tmp(4) + tmp(5), 16)];
};
var color = x16to10(start),
var end = x16to10(end),
var index = 3;
while(index--)
color[index] = color[index] < end[index] ? min(color[index] + speed, end[index]) : max(color[index] - speed, end[index]);
reutn color;
}
有兴趣的诸位可以自己实现一下这个通用动画函数