原生JS实现元素的多值运动

原生JS实现元素的多值运动

原生JS实现元素的多值运动。

在介绍JS运动内容时,我们陆续介绍了简单的运动,图片透明度运动,摩擦运动和缓冲运动。这些运动基本上都是一个元素的单一运动。如果在一个元素身上同时发生两种运动形式呢?应该比如当鼠标点击元素时,元素的宽和高同时发生改变,或者先改变元素的宽,再改变元素的高,发生在一个元素上的这种运动形式就叫多值运动,应该如何操作?

1、当改变的宽高距离一样

在同一时间内,元素的宽高改变是一样值的时候,这个时候可以一起运动。但是同时改变宽和高,按理来说我们要用到数组,但数组不好调用。如果将两个宽高运动拆开来运动,下面的定时器会清除掉上面的定时器。我们考虑用JSON来操作。直接调用函数的形式来操作。

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<style>
#div1 {width:100px; height: 100px; background: red; position: absolute; left: 0px; top: 30px; left: 400px;}
</style>
<script>
window.onload = function() {
	
	var oDiv1 = document.getElementById('div1');

	//用JSON方式调用函数
	oDiv1.onclick = function() {
		
		startMove(this, {
			width : 200,
			height: 200
		}, 10);
	}
	
	function startMove(obj, json, iSpeed) {
		clearInterval(obj.iTimer);//开始清除定时器
		var iCur = 0;
			
		obj.iTimer = setInterval(function() {
			
			for ( var attr in json ) {
				
				var iTarget = json[attr];
				
				if (attr == 'opacity') {
					iCur = Math.round(css( obj, 'opacity' ) * 100);
				} else {
					iCur = parseInt(css(obj, attr));
				}
				
				if (iCur == iTarget) {
					clearInterval(obj.iTimer);
				} else {
					if (attr == 'opacity') {
						obj.style.opacity = (iCur + iSpeed) / 100;
						obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')';
					} else {
						obj.style[attr] = iCur + iSpeed + 'px';
					}
				}
			}
			
		}, 30);
	}
	
	function css(obj, attr) {
		if (obj.currentStyle) {
			return obj.currentStyle[attr];
		} else {
			return getComputedStyle(obj, false)[attr];
		}
	}
	
}
</script>
</head>

<body>
	<div id="div1"></div>
</body>
</html>

在线操作

如果改变的宽高是不一样的值会发生什么呢?在同一时间内,如果宽高改变的值不一样,那么改变的最长的那边将不会达到目标,运动就会停止。

2、当改变的宽高不一致时

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<style>
#div1 {width:100px; height: 100px; background: red; position: absolute; left: 0px; top: 30px; left: 400px;}
</style>
<script>
window.onload = function() {
	
	var oDiv1 = document.getElementById('div1');
	
	oDiv1.onclick = function() {
		
		startMove(this, {
			width : 200,
			height: 300
		}, 10);
	}
	
	function startMove(obj, json, iSpeed) {
		clearInterval(obj.iTimer);
		var iCur = 0;
			
		obj.iTimer = setInterval(function() {
			
			var iBtn = true;
						
			for ( var attr in json ) {
				
				//什么时候停止定时器?所有属性都运动到了目标点的时候
				
				var iTarget = json[attr];
				
				if (attr == 'opacity') {
					iCur = Math.round(css( obj, 'opacity' ) * 100);
				} else {
					iCur = parseInt(css(obj, attr));
				}
				
				if (iCur != iTarget) {
					iBtn = false;
					if (attr == 'opacity') {
						obj.style.opacity = (iCur + iSpeed) / 100;
						obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')';
					} else {
						obj.style[attr] = iCur + iSpeed + 'px';
					}
				}
				
			}
			
			//在这里来看下,所有属性是不是都到了目标点
			if (iBtn) {
				clearInterval(obj.iTimer);
			}
			
		}, 30);
	}
	
	function css(obj, attr) {
		if (obj.currentStyle) {
			return obj.currentStyle[attr];
		} else {
			return getComputedStyle(obj, false)[attr];
		}
	}
	
}
</script>
</head>

<body>
	<div id="div1"></div>
</body>
</html>

在线操作

上面两个例子都是宽高一起运动,如果宽高改变值不一致的情况下,先一起运动,高再继续运动。如果我们想要先改变宽度,当宽度到达目标点后,再改变高度值,如何操作呢?

3、先改变宽度值,再改变高度值

那我们需要调用两次函数,先改变宽度值,然后再改变高度值。其余的原理,运动过程都差不多,只是在最后停止定时器的时候,为了兼容性问题,要用到IE下的call()属性

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<style>
#div1 {width:100px; height: 100px; background: red; position: absolute; left: 0px; top: 30px; left: 400px;}
</style>
<script>
window.onload = function() {
	
	var oDiv1 = document.getElementById('div1');
	
	oDiv1.onclick = function() {
		
		startMove(this, {
			width : 200
		}, 10, function() {
			startMove(this, {
				height : 200
			}, 10);
		});
	}
	
	function startMove(obj, json, iSpeed, fn) {
		clearInterval(obj.iTimer);
		var iCur = 0;
			
		obj.iTimer = setInterval(function() {
			
			var iBtn = true;
						
			for ( var attr in json ) {
								
				var iTarget = json[attr];
				
				if (attr == 'opacity') {
					iCur = Math.round(css( obj, 'opacity' ) * 100);
				} else {
					iCur = parseInt(css(obj, attr));
				}
				
				if (iCur != iTarget) {
					iBtn = false;
					if (attr == 'opacity') {
						obj.style.opacity = (iCur + iSpeed) / 100;
						obj.style.filter = 'alpha(opacity='+ (iCur + iSpeed) +')';
					} else {
						obj.style[attr] = iCur + iSpeed + 'px';
					}
				}
				
			}
			
			if (iBtn) {
				clearInterval(obj.iTimer);
				fn && fn.call(obj);
			}
			
		}, 30);
	}
	
	function css(obj, attr) {
		if (obj.currentStyle) {
			return obj.currentStyle[attr];
		} else {
			return getComputedStyle(obj, false)[attr];
		}
	}
	
}
</script>
</head>

<body>
	<div id="div1"></div>
</body>
</html>

在线操作


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值