Dom元素變換效果(工具函數(shù))
用js來控制行為,控制頁面表現(xiàn)。恐怕是我們用它來做的最多的事情了...
jQuery為什么這么受歡迎,我想,一方面是它的選擇器[selector]足夠牛B,另一方面應該要歸功于它在dom變換上做足了功夫。
于是,秉承著一個宅男的宗旨,周末花了兩個晚上稍微總結了一下,寫了一段控制dom元素變換的代碼,與目前強大的框架比起來,確實顯得有點拙劣,不過作為日常開發(fā)的工具函數(shù),我想還是蠻實用的。(這也是我最初的目的 ^_^)。
開門見山,先把源碼完整的貼出來:(本著分享學習的原則,源代碼你可以任意修改)
//////////////* = 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();
}
}
}
從調用方式來看,其實我的實現(xiàn)方法有點類似于YUI,以下是個最簡單的例子:
Hongru.anim(id, {
from: {
top: 0,
left: 100
},
to: {
left: 500,
}
});
以下是調用這段代碼的效果:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
當然,這是最簡單的方式,此外,我在參數(shù)id上,花了點小心思,anim()的第一個參數(shù)不僅可以是我們常見的字符串"id",也可以是HtmlObject,比如同樣是上面的代碼:
function tween1 (id) { //此id參數(shù)可以是obj,也可以是字符串id,還可以是數(shù)組['id1','id2','id3']
Hongru.anim(id, {
from: {
top: 0,
left: 100
},
to: {
left: 500,
}
});
}
可以對一個元素這樣來調用
onclick="tween1(this)"
this直接指向元素本身,演示如下。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
另外,還可以控制多個元素同時變換,也就是說,id可以是個數(shù)組如['id1', 'id2', 'id3'].演示如下:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]