• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
00fairy00の学习园地
博客园    首页    新随笔    联系   管理    订阅  订阅
NO.51
View Code
  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  &#160;  动画测试 &#160;
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  &#160;
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  &#160;
148 <input type="button" value="透明度变化"
149 onClick="fade('testDiv', rand(5,100))" />
150  &#160;
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>
var fade = function(element, transparency, speed, callback){……}
透明度渐变: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;
}


有兴趣的诸位可以自己实现一下这个通用动画函数
posted on 2011-02-24 16:30  00fairy00  阅读(283)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3