一、JavaScript运动函数封装
常用参数声明:
- dom(object) : dom元素,通过document.getElementsByTagName等操作获取到的元素
- target (number) : 运动的目标数值
- speed (number):匀速运动的速度
- arr (string):需要修改的属性名
- parmobj (object):需要修改的参数对象列表
1.匀速运动函数封装
function uniformSpeed(dom,target,speed){
clearInterval(dom.timer);
//注意点1:
var iSpeed = target - dom.offsetLeft > 0 ? speed:-speed;
dom.timer = setInterval(function(){
//注意点:2:
if(Math.abs(target - dom.offsetLeft) < Math.abs(iSpeed)){
dom.style.left= target +'px';
clearInterval(dom.timer);
}else{
dom.seyle.left = dom.offsetLeft + iSpeed +'px';
}
},30)
}
- 首先我们需要注意的是iSpeed的值,当target的值大于元素当前值的时候,我们移动的是正值,即向左移动,反之则向右。
- 其次我们需要注意的是判断条件,因为我们传入的参数速度值,可能千奇百怪,所以不能完美的累加到目标值,所以我们判断的临界值为,当目标值减去当前值如果小于速度的话,就直接让元素到达目标值。
- 还有一点需要我们特别注意,就是dom.timer的写法,是为了防止当多个元素同时运行时,会清除其他元素定时器的情况
2.减速(缓速)运动
function decelerationSpeed(dom,target){
clearInterval(dom.timer);
dom.timer = function(){
var iSpeed = (target - dom.offsetLeft)/7;
//注意点1:
iSpeed = iSpeed > 0 ? Math.ceil(iSpedd) : Math.floor(iSpeed);
if(target == dom.offsetLeft){
clearInterval(dom.timer);
}else{
dom.style.left = dom.offsetLeft + iSpeed + 'px';
}
}
}
- 这里我们需要特别注意一下速度的计算方法,因为我们做减速运动时,是目标值减去当前值除以7得到的,所以他每次得到的并非是整数,这是就会出现一种情况,就是元素的移动距离无法到达目标值,因为css在渲染小数时会将297.12之类的数字渲染成297
假设我们的目标值是300px,假设当你移动到最后的时候元素的left值为297.429的时候,那么css会认为他是297,所以目标值减去当前值为 300-297=3,然后下次移动的速度iSpeed = 3/7 = 0.428,那么下次元素的left的值是 297+0.428 = 297.428,所以此时他就陷入了死循环,那么此时我们需要做的就是向上取整,当是正数的时候我们向上取整,其实到最后的速度就几乎都是1,这时就可以准确到达我们的目标值了。
3.透明度运动
// 获取元素的样式
function getStyle(dom, arr) {
if (window.getComputedStyle) {
return window.getComputedStyle(dom, null)[arr];
} else {
return dom.currentStyle[arr]; //该方法只存在于IE中
}
}
function startMove(dom,target){
clearInterval(timer);
timer = setInterval(function(){
var iCur = parseFloat(getStyle(dom,'opacity')),//获取当前元素的样式值
iSpeed = ((target -iCur)/7)*100;//注意点1:
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed):Math.floor(iSpeed);
if(iCur == target){
clearInterval(timer);
}else{
dom.style.opacity = iCur + iSpeed/100;//注意点2:
}
},30)
}
- 因为透明度属性比较特别,他是数值后面不加像素的所以我们单独拿出来处理。
- 因为透明度的值是[0,1],所以我们需要将每次的变化值ispeed乘以100,如果不乘的话向上向下取整就直接是1或者-1,那么透明度就超范围了
4.综合运动(多物体多状态&&回调函数)
function startMove(dom, arrobj, callback) {
clearInterval(dom.timer);
dom.timer = setInterval(function() {
var iSpeed = null,
iCur = null,
stopFlag = true;
for (var arr in arrobj) {
iCur = parseFloat(getStyle(dom, arr));
if (arr === 'opacity') {
iSpeed = (arrobj[arr] - iCur) / 7 * 100;
} else {
iSpeed = (arrobj[arr] - iCur) / 7;
}
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
if (arr === 'opacity') {
dom.style.opacity = iCur + iSpeed / 100;
} else {
dom.style[arr] = iCur + iSpeed + 'px';
}
if(iCur != arrobj[arr]){
stopFlag = false;
}
}
if (stopFlag) {
clearInterval(dom.timer);
typeof callback == 'function' && callback();
}
}, 30)
}