js运动(一)—— sidebar(分享到)

1.前言

在一些网页中,经常可以看到边框上,有一个“分享到”的小标签,鼠标进入后,划出一个小框,上面是微信、QQ等选项。这个效果可以使用js运动来实现。

尽管在现实开发中,运动可能大都使用 jQuery 等框架来完成,但是生js编码还是要熟悉一下。

在学习过程中,看着挺简单的,结果是脑子会了,自己做得时候手没跟上(主要是布局方面),所以即使看起来简单的东西还是要自己做自己积累。

2. 运动原理

一般情况下,可通过设置元素的一些属性,如长宽高、边框、位置、透明度等,达到运动的效果。
当需要匀速或变速运动时,只需要使用定时器逐次增加或减少即可。

3. sidebar初试

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>sidebar</title>
<style>
#div1 {width:150px; height:200px; left:-150px; position:absolute; background-color:red;}
#div1 span {position:absolute; width:20px; height:100px; line-height:20px; right:-20px; top:70px;  background-color:green;}
</style>

<script>
window.onload = function(){
	var oDiv = document.getElementById("div1");
	//注意,使用的div来作为监听对象,而不是span。span范围很小,不利于鼠标移入移出,
	//会造成抖动
	oDiv.onmouseover =  function(){
		oDiv.style.left = 0 + "px";
	};
	
	oDiv.onmouseout =  function(){
		oDiv.style.left = -150 + "px";
	};
}
</script>
</head>

<body>
<div id="div1">
	<span>分享到</span>
</div>
</body>
</html>

大致效果如下。
鼠标未进入

鼠标进入后
关于布局,慢慢弄懂了一些东西:

1.div1的长、宽都为100px,为了程序刚运行的时候不可见,所以设置绝对定位,left为-100px。

2.span为div1的子元素,且为绝对定位。line-height指定行高,也即“分享到”这三个字每个字的垂直距离。关于right:-20px这点想了很久才想明白。绝对定位相对于已经定位过的祖先元素(找到为止,父元素没有定位则找父元素的父元素,直到相对于文档本身)。详细说明如下。

<style>
#div1 {width:150px; height:200px; left:-150px; position:absolute; background-color:red;}
#div1 span {position:absolute; width:20px; height:100px; line-height:20px; left:150px; top:70px;  background-color:green;}
</style>

把right:-20px修改成left:150px是一样的结果。
改成left:150px
经过系列摸索,得到结论如下(图中的数据为说明用,与上方测试数据不一)。
在这里插入图片描述

4.匀速

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>sidebar</title>
<style>
#div1 {width:150px; height:200px; left:-150px; position:absolute; background-color:red;}
#div1 span {position:absolute; width:20px; height:100px; line-height:20px; right:-20px; top:70px;  background-color:green;}
</style>

<script>
var timer = null;
window.onload = function(){
	var oDiv = document.getElementById("div1");
	
	oDiv.onmouseover =  function(){
		//oDiv.style.left = 0 + "px";
		moveTo(oDiv, 0 )
	};
	
	oDiv.onmouseout =  function(){
		//oDiv.style.left = -150 + "px";
		moveTo(oDiv, -150 )
	};
}

function moveTo(obj, iTarget){
	var speed;
	clearInterval(timer);
	if(obj.offsetLeft>iTarget)
		speed = -10;
	else
		speed =10;
		
	 timer = setInterval(function(){
		if(obj.offsetLeft == iTarget)
			clearInterval(timer);
		else
			obj.style.left = obj.offsetLeft + speed + "px";	
	},30);
		
}

</script>

</head>

<body>
<div id="div1">
	<span>分享到</span>
</div>
</body>
</html>

1.为了重复使用代码,所以封装了函数
2.为了每次鼠标进入移除之间不互相干扰引发错误,每次实际运动前现将定时器关闭。
3.匀速运动过程中会遇到一个问题,即当距离不能被速度整除的话,整个运动可能会一直持续,而非到点停止。例如,本例中,当speed=7时,因为距离为150px,后者不能被前者整除,会出现下图这种情况,可以看到,left已经完全脱离0点。

在这里插入图片描述
可行的一种解决办法是,告诉浏览器,在一定范围内就算到了,加上whenArrival函数,如下。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
#div1 {width:150px; height:200px; left:-150px; position:absolute; background-color:red;}
#div1 span {position:absolute; width:20px; height:100px; line-height:20px; right:-20px; top:70px;  background-color:green;}
</style>

<script>
var timer = null;
window.onload = function(){
	var oDiv = document.getElementById("div1");
	
	oDiv.onmouseover =  function(){
		//oDiv.style.left = 0 + "px";
		moveTo(oDiv, 0 )
	};
	
	oDiv.onmouseout =  function(){
		//oDiv.style.left = -150 + "px";
		moveTo(oDiv, -150 )
	};
}

function moveTo(obj, iTarget){
	var speed;
	clearInterval(timer);
	if(obj.offsetLeft>iTarget)
		speed = -7;
	else
		speed = 7;
		
	 timer = setInterval(function(){
		/*if(obj.offsetLeft == iTarget)
			clearInterval(timer);
		else
			obj.style.left = obj.offsetLeft + speed + "px";	*/
		whenArrival(obj, iTarget, speed);
	},30);	
}

function whenArrival(obj, iTarget, speed){
	if(Math.abs(obj.offsetLeft - iTarget) <= Math.abs(speed)){
		clearInterval(timer);
		obj.style.left = iTarget + "px";
 	}else{
 		obj.style.left = obj.offsetLeft + speed + "px";	
 	}
}

</script>

</head>

<body>
<div id="div1">
	<span>分享到</span>
</div>
</body>
</html>

whenArrival函数中,需要注意的是,Math.absMath是大写的;另外,

obj.style.left = iTarget + "px";

obj.style.left = obj.offsetLeft + speed + "px";	

后面的px单位不能忘。

5.缓动

缓动,也即速度与距离成正比,只需将原先定死的速度写成灵活的,如下:

speed = (obj.offsetLeft - iTarget)/  7;

但是,这个方法还有一个问题。最小单位是1px,经上式算出来的速度,出现小数是不可避免的,这就要用到向上取整或者向下取整了。

speed=speed>0?Math.ceil(speed):Math.floor(speed);

不需要用到whenArrival函数。因为缓动时速度可变,最后速度取整总会能出现1。

function moveTo(obj, iTarget){
var speed;
clearInterval(timer);
speed = (iTarget-obj.offsetLeft)/7;
speed=speed>0?Math.ceil(speed):Math.floor(speed);
timer = setInterval(function(){
if(obj.offsetLeft == iTarget)
clearInterval(timer);
else
obj.style.left = obj.offsetLeft + speed + “px”;
},30);
}

缓动还存在一个隐藏的问题。因为目标值有可能是计算所得,所以目标值也存在不是整数的情况。又因为最小单位为1像素,所以当出现这种情况时,需要使用 parseInt 函数对目标值取整。这将到位的元素与实际需要达到的元素存在些许差别。

6.总结

内容比较简单,但重在积累,加油!
1.运动的思想:属性改变
2.匀速运动思想:速度恒定
3.缓动思想:速度随着距离改变
4.缓动中速度取整、匀速中到达目标点的判断很重要,处理运动时,这方面思想不能少
5.开发中比较容易遗漏单位,应仔细检查,否则无法达到预期效果,且不会报错。
6.关于布局方面的知识应当加强。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值