用js来控制行为,控制页面表现。恐怕是我们用它来做的最多的事情了... 
  jQuery为什么这么受欢迎,我想,一方面是它的选择器[selector]足够牛B,另一方面应该要归功于它在dom变换上做足了功夫。 
  于是,秉承着一个宅男的宗旨,周末花了两个晚上稍微总结了一下,写了一段控制dom元素变换的代码,与目前强大的框架比起来,确实显得有点拙劣,不过作为日常开发的工具函数,我想还是蛮实用的。(这也是我最初的目的 ^_^)。 
  开门见山,先把源码完整的贴出来:(本着分享学习的原则,源代码你可以任意修改) 
复制代码 代码如下: 
//////////////* = Hongru.anim.js =*/////////// 
// @author: hongru.chen // 
// @date: 2010-10-17 // 
//////////////////////////////////////////// 
var Hongru = { 
get : function (id) {return document.getElementById(id)}, 
tween : { 
linear : function (f, t, d) { return t * d + f; }, 
ease : function (f, t, d) { return -t * .5 * (Math.cos(Math.PI * d) - 1) + f; } 
}, 
tweens: [], 
tweensCnt: 0, 
anim : function (obj, params) { 
var self = this, 
objList = [], 
objReturn = []; 
var animimg = function () { 
var i = -1, o; 
while( o = self.tweens[++i] ) { 
var cTime = (new Date()).getTime() - o.start; 
if (cTime < o.duration) { 
for (var k in o.val) { 
var m = o.val[k]; 
o.obj[k] = Math.ceil(o.ease(m.from, m.diff, cTime/o.duration)) + (o.cssMode ? 'px' : 0); 
} 
} else { 
cTime = o.duration; 
for (var k in o.val) { 
var m = o.val[k]; 
o.obj[k] = Math.ceil(o.ease(m.from, m.diff, cTime/o.duration)) + (o.cssMode ? 'px' : 0); 
} 
self.tweens.splice(i, 1); 
self.tweensCnt--; 
if (o.onFinish) o.onFinish (o.params); 
self.stop(); 
} 
if (!o.cssMode) o.obj.onTween(); 
} 
}; 
if (typeof obj == "string" || !obj.length) objList.push(obj); else objList = obj; 
for (var il = 0, l = objList.length; il < l; il++) { 
var obj = this.get(objList[il]) || objList[il]; 
var o = {}; 
o.val = {}; 
o.cssMode = true; 
o.o = obj; 
o.obj = obj.style; 
for (var k in params) { 
var p = params[k]; 
if (k === "cssMode") { 
if (p === false) { 
o.cssMode = false; 
o.obj = obj; 
} 
} else if (k === "onTween") { 
o.obj.onTween = p; 
} else if (k === "from") { 
for (var i in p) o.obj[i] = o.cssMode ? (Math.ceil(p[i]) + 'px') : p[i]; 
} else if (k === "to") { 
for (var i in p) { 
var from = o.cssMode ? (parseInt(o.obj[i]) || 0) : (o.obj[i] || 0); 
o.val[i] = { 
from: from, 
diff: p[i] - from 
}; 
} 
} else o[k] = params[k]; 
} 
if (!o.ease) o.ease = this.tween.ease; 
if (!o.cssMode && params['from']) o.obj.onTween(); 
o.duration = params.duration ? params.duration : 1000; 
o.start = (new Date()).getTime(); 
this.tweens.push(o); 
this.tweensCnt++; 
if (!this.running) this.running = window.setInterval(animimg, 10); 
objReturn.push(o); 
} 
return objReturn.length === 1 ? o : objReturn; 
}, 
stop : function () { 
if (!this.tweensCnt) { 
window.clearInterval(this.running); 
this.running = false; 
} 
}, 
kill : function (obj) { 
if (obj) { 
for (var i = 0; i < this.tweensCnt; i++) { 
if (this.tweens[i] === obj || this.tweens[i].o === obj || this.tweens[i].o === this.get(obj)) { 
this.tweensCnt--; 
this.tweens.splice(i, 1); 
this.stop(); 
} 
} 
} 
}, 
reset : function () { 
this.tweensCnt = 0; 
this.stop(); 
while( this.tweens.length ) { 
this.tweens.stop(); 
} 
} 
} 
 
从调用方式来看,其实我的实现方法有点类似于YUI,以下是个最简单的例子: 
复制代码 代码如下: 
Hongru.anim(id, { 
from: { 
top: 0, 
left: 100 
}, 
to: { 
left: 500, 
} 
}); 
 
以下是调用这段代码的效果: 
  [Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行] 
当然,这是最简单的方式,此外,我在参数id上,花了点小心思,anim()的第一个参数不仅可以是我们常见的字符串"id",也可以是HtmlObject,比如同样是上面的代码: 
复制代码 代码如下: 
function tween1 (id) { //此id参数可以是obj,也可以是字符串id,还可以是数组['id1','id2','id3'] 
Hongru.anim(id, { 
from: { 
top: 0, 
left: 100 
}, 
to: { 
left: 500, 
} 
}); 
} 
 
可以对一个元素这样来调用 
onclick="tween1(this)" 
this直接指向元素本身,演示如下。 
  [Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行] 
另外,还可以控制多个元素同时变换,也就是说,id可以是个数组如['id1', 'id2', 'id3'].演示如下: 
  [Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行] 
以上可以支持object和数组selector的功能,暂可以称为【功能一】, 
  【功能二】 
支持回调函数callback,也就是可以实现咱们常说的chain-animate,链式变换。具体是通过onFinish参数来实现的。核心源码很简单,就是在一个变换完毕之后判断有没有onFinish,如果有就调用: 
复制代码 代码如下: 
var animimg = function () { 
var i = -1, o; 
while( o = self.tweens[++i] ) { 
var cTime = (new Date()).getTime() - o.start; 
if (cTime < o.duration) { 
for (var k in o.val) { 
var m = o.val[k]; 
o.obj[k] = Math.ceil(o.ease(m.from, m.diff, cTime/o.duration)) + (o.cssMode ? 'px' : 0); 
} 
} else { 
cTime = o.duration; 
for (var k in o.val) { 
var m = o.val[k]; 
o.obj[k] = Math.ceil(o.ease(m.from, m.diff, cTime/o.duration)) + (o.cssMode ? 'px' : 0); 
} 
self.tweens.splice(i, 1); 
self.tweensCnt--; 
if (o.onFinish) o.onFinish (o.params); 
self.stop(); 
} 
if (!o.cssMode) o.obj.onTween(); 
} 
}; 
 
下面是通过递归调用实现chain-animate的一个演示: 
  [Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行] 
到这里,相信以前做过类似工作的同学们都觉得这还不够,毕竟如果只实现所有和‘盒模型'沾边的属性的变换应该都不算难事。比如高宽,padding,margin,left,top等等这些可以用像素做单位的属性。他们的变换都可以统一起来。但是如果要实现颜色变换,透明度变换呢,恐怕就不是我的短短几十百来行代码就可以做到的。 
是的,我承认,要把颜色,透明度等等所有属性变换都封装起来,需要做的判断就不是一点两点了。所以呢,在这里,我也没有对“盒模型”以外的属性变换做封装。但并不代表没有想到他们的实现方法。 
  既然写死在代码里要费事,那就我们自己调用的时候多写两句代码不就好了吗,毕竟代码是死的,人是活的。我这里做了个cssMode的参数判断(思路是借鉴一个老外的)。代码成本很低。如果不是可以用px做单位的属性,我们可以自己控制它的样式变换。比如实现背景色变换: 
复制代码 代码如下: 
function test3 (id) { 
Hongru.anim(id, { 
cssMode: false, // animation will be handled by an external function 
onTween : function () { 
// custom function, can be as simple or as complex as needed 
this.style.background = "RGB("+this.r+","+this.g+","this.b")"; 
}, 
from : { r: 0, g: 0, b: 0 }, 
to: { r: 255, g: 128, b: 100 } 
}); 
} 
 
把cssMode设置为false之后,会执行onTween里的代码,这样就可以自行控制样式的变换了,如上。演示如下: 
  [Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行] 
同样,透明度也可以自行设置, 
  [Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行] 
好了,鉴于篇幅和时间,此文基本都在介绍功能,对代码没怎么细讲,有兴趣的同学可以自己看看,反正源码也贴出来了,而且原理都不难。 
另外,在这个函数使用中,Hongru.kill(id)是停止指定对象的变换。Hongru.reset()是停止所有正在变换的效果。至于Hongru本身,大家可以随意更改。 
Dom,元素变换
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?