模仿jQuery的slideDown、slideUp上下滑动,舒服!

效果图:

全部代码如下:


<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=GBK">
        </head>
        <body>
	        <div id="div" style="width:300px;height:50px;background:skyblue;"><p>div</p></div>
	        
	        <button onclick="do_slideUp()">slideUp Div</button>
	        
	        <button onclick="do_slideDown()">slideDown Div</button>
	       
	       	<button onclick="do_slideToggle()">slideToggle Div</button> 
	        
	        
        </body>
<script>

//获取属性值
function getStyle(obj, prop) {
	var prevComputedStyle = document.defaultView ? document.defaultView.getComputedStyle( obj, null ) : obj.currentStyle;
	return prevComputedStyle[prop];
}
	
/*
	obj:dom对象
	prop:动画参数
	speed:执行速度 fast slow 3000等
	func:回调函数
*/
function animate(obj,prop,speed,func){
	//防止重复动画事件
	if(obj.timer) return ;
	//定义定时器执行次数和总执行时间
	var	limit=10,totalTime; 
	if(typeof speed==='number'){//如果传入的是
		totalTime = speed;
	}else if(speed==='slow'){
		totalTime = 600;
	}else if(speed==='fast'){
		totalTime = 200;
	}else{
		totalTime = 400;
	}
	
	var time = totalTime/limit;

	var n=0,cache={},display,primary_cur;//cache用来缓存,省的每次都去dom获取
	obj.timer = setInterval(function(){
		n++;//执行次数每次递增
		for(var p in prop){
			if("display"===p) {
				display = prop["display"];
				if(display!=='none'){
					obj.style['display'] = display;
				}
				delete prop["display"];
				continue;
			}
			//判断是否是可以递增的属性,如果不是则直接让它生效,并从prop中删除,删除后就不用每次任务都执行它
			var reg = /^(\d)+(px$)?/;//数字和像素这样的判定为可以递增的属性
			if(!reg.test(prop[p])){
				obj.style[p] = prop[p];
				delete prop[p];
				continue;
			}
			
			var value,opacityFlag=(p == "opacity")?true:false;
			var cur = 0;
			if(cache[p+"_cur"]){//从缓存中取
				cur = cache[p+"_cur"];
				value = cache[p+"_value"];
			}else{
				value = prop[p];
				if(opacityFlag) {
					//如果本来是隐藏的则cur默认就是0
					if(getStyle(obj, 'display')!=='none'){
						cur = Math.round(parseFloat(getStyle(obj, p)) * 100);
					}
				} else {
					cur = parseInt(getStyle(obj, p));
					//处理100px的格式
					(typeof value==='string') && (value=value.replace(/px$/,""));
				}
				primary_cur=cur;
				cache[p+"_value"] = value;
			}
			
			var incre ;
			if(cache[p+'_increment']){//如果缓存中有则从中取
				incre = cache[p+'_increment'];
			}else{
				if(opacityFlag){
					incre = (value*100-cur)/limit;//计算每次变化值
				}else{
					incre = (value-cur)/limit;//计算每次变化值
				}
				cache[p+'_increment']= incre;
			}
			//缓存起来,这样就不用每次都去dom中获取了。
			cache[p+"_cur"] = cur + incre;
			
			if (opacityFlag) {
				//obj.style.filter = "alpha(opacity : '+(cur + incre)+' )";
				obj.style.opacity = (cur + incre)/100 ;
			}else {
				obj.style[p] = cur + incre + "px";
			}
		}
		//如果达到了最大执行次数,要清除定时器,并执行回调函数
		if(n==limit){
			if(display==='none'){
				obj.style['display'] = 'none';
			}
			//清除定时器
			clearInterval(obj.timer);
			obj.timer=undefined;
			func && func();
		}
	},time)
	
}
var div = document.getElementById("div");

/*
	obj:dom对象
	speed:执行速度 fast slow 3000等
	func:回调函数
*/

function slideUp(obj,speed,func){
	if(obj.style.display==='none'){
		return ;
	}
	//获取本来的宽带和高度
	var height = getStyle(obj, 'height');
	var new_func = function(){
		//设置回原来的高度和宽度
		obj.style['height'] = height ;
		func();
	}
	animate(obj,{display:'none',height:0},speed,new_func);
}

function slideDown(obj,speed,func){
	if(obj.style.display!=='none'){
		return ;
	}
	//获取本来的宽带和高度
	var height = getStyle(obj, 'height');
	//设置从0开始
	obj.style['height'] = 0 ;
	animate(obj,{display:'block',height:height},speed,func);
}

function slideToggle(obj,speed,func){
	if(obj.style.display==='none'){
		slideDown(obj,speed,func);
	}else{
		slideUp(obj,speed,func);
	}
}

//执行显示
function do_slideUp(){
	//执行速度 fast slow 3000等
	slideUp(div,1000,function(){
		console.log('slideUp_finished')
	})
}

//执行隐藏
function do_slideDown(){
	//执行速度 fast slow 3000等
	slideDown(div,1000,function(){
		console.log('slideDown_finished')
	})
}

function do_slideToggle(){
	slideToggle(div,'fast',function(){
		console.log('toggle_finished')
	});
}


</script>
</html>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程界小明哥

请博主喝瓶水,博主持续输出!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值