javascript DOM编程艺术学习笔记(7)动画案例2:

****动画2:
1.为所有预览图片生成一张“集体照”形式的照片;
2.隐藏这张“集体照”图片的绝大部分;
3.当用户把鼠标指针悬停在某个链接上时,只显示这张“集体照”图片的相应部分;
版本1.0:
<!-- HTML代码 -->
<body>
	<h1>点击链接切换照片</h1>
	<ul id="linklist">
		<li><a href="">向上</a></li>
		<li><a href="">向右</a></li>
		<li><a href="">向下</a></li>
		<li><a href="">向左</a></li>
		
	</ul>
	<div id="moveDiv">
		<img src="tank.gif" alt="tank" id="moveImg" />
	</div>

</body>

/*CSS代码*/
#moveDiv{
	width:40px;
	height: 40px;
	overflow: hidden;
	position: relative;
}
#moveImg{
	position:absolute;
	/*left: 0px;
	top: 0px;*/
}

//JSd代码:
function prepareSlideShow(){
	//获取移动的集体照并设置他的位置样式属性
	var moveImg=document.getElementById("moveImg");
	moveImg.style.postion="absolute";
	moveImg.style.left="0px";
	moveImg.style.top="0px";
	//获得所有的链接元素
	var linklist=document.getElementById("linklist");
	var links=linklist.getElementsByTagName("a");

	//绑定onmouseover事件,根据不同的链接元素传入不同的参数进行照片切换
	//向上
	links[0].οnmοuseοver=function(){
		movement("moveImg",0,0,10);
		}
	//向右
	links[1].οnmοuseοver=function(){
		movement("moveImg",0,-40,10);
		}
	//向下
	links[2].οnmοuseοver=function(){
		movement("moveImg",0,-80,10);
		}
	//向左
	links[3].οnmοuseοver=function(){
		movement("moveImg",0,-120,10);
		}

	
}

//之前写好的每个inteval时间移动特定id名为elementId元素到目的地(final_x,final_y)
function movement(elementId,final_x,final_y,interval){
	
	var moveDiv=document.getElementById(elementId);
	//通过parseInt来提取字符串中的数字
	var xpos=parseInt(moveDiv.style.left);
	var ypos=parseInt(moveDiv.style.top);
	// alert("aa");
	if(xpos==final_x&&ypos==final_y){
		return true;
	}
	if(xpos<final_x){
		xpos++;
	}else{
		xpos--;
	}

	if(ypos<final_y){
		ypos++;
	}else{
		ypos--;
	}

	//一定要记得改变位置后要把新的位置返还给style属性;
	//这是又要注意style属性值是字符串的,所以不要忘记加”px“
	moveDiv.style.left=xpos+"px";
	moveDiv.style.top=ypos+"px";
	//一定要注意在moveMessage中参数elementId是字符串,所以在做字符串拼接的时候一定要注意要额外为其添加
	//单引号以突出他是字符串,不然会出错
	var repeat="movement('"+elementId+"',"+final_x+","+final_y+","+interval+")";
	
	//这边最好把setTimeout返回值给保存在movement中,便于清除
	movement1=setTimeout(repeat,interval);
}
addLoadEvent(prepareSlideShow);
***改进1:
bug分析:

1.上面的版本会出现动画混乱的Bug,当把鼠标指针在链接之间快速来回地切换,动画将变得混乱都动起来;
2.当用户把鼠标移动在链接上时,不管上次调用是否已经把图片移动到位,movement都会被再次调用试图把这个图片
移动到另一个地方去;于是用户在链接上来回移动时,movement1变量也会像拔河绳那样来回变化;
直接导致setTimeout队列中有多个事件等待执行,从而导致动画混乱抖动;
3.所以应该用clearTimeout来清除积累在setTimeout队列里的事件;

解决:我们通过为移动图片元素定义一个movement1变量来绑定该元素;每次进入到movement()函数时在获取
moveImg后,通过判断当前moveImg元素是否存在一个movement1变量,来决定是否用clearTimeout来清除setTimeout
动画队列中的事件,这样一来,不管鼠标快速一进一出链接多少次,在setTimeout动画队列中始终只有一条setTimeout
函数调用语句;


**改进2:
我们希望根据图片元素当前位置和目的地位置的差值来确定他们的移动速度;

解决:
1.新定义一个变量用于存储位置差(dist)
2.计算dist(正整数):根据两者的位置差取百分之十,然后要向上取整,这样做是为了避免两者距离差小于1的情况;
3.将dist累加或累减至图片当前位置;

具体实现:

var dis=0;
dist=Math.ceil((final_x-xpos)/10);
xpos+=dist;
为每一种情况都运用类似的方法代码;


****改进3:
添加安全性的检查;进入movement()函数获取移动图片元素后,我们需要判断元素是否已经设置left和top属性值;
这样才能进行后续的移动,如果没有则需要我们做判断添加:
if(!moveImg.style.left){
	moveImg.style.left="0px";
}
if(!moveImg.style.top){
	moveImg.style.top="0px";
}
改进后的JS代码:

//JSd代码:
function prepareSlideShow(){
	//获取移动的集体照并设置他的位置样式属性
	var moveImg=document.getElementById("moveImg");
	
	//获得所有的链接元素
	var linklist=document.getElementById("linklist");
	var links=linklist.getElementsByTagName("a");

	//绑定onmouseover事件,根据不同的链接元素传入不同的参数进行照片切换
	//向上
	links[0].οnmοuseοver=function(){
		movement("moveImg",0,0,10);
		}
	//向右
	links[1].οnmοuseοver=function(){
		movement("moveImg",0,-40,10);
		}
	//向下
	links[2].οnmοuseοver=function(){
		movement("moveImg",0,-80,10);
		}
	//向左
	links[3].οnmοuseοver=function(){
		movement("moveImg",0,-120,10);
		}

	
}

//之前写好的每个inteval时间移动特定id名为elementId元素到目的地(final_x,final_y)
function movement(elementId,final_x,final_y,interval){
	
	var moveImg=document.getElementById(elementId);
	//清除setTimeout中多个动画事件,使其中队列中始终只有一个函数调用
	if(moveImg.movement1){
		clearTimeout(moveImg.movement1);
	}
	//安全性检查是否设定left top属性值
	if(!moveImg.style.left){
		moveImg.style.left="0px";
	}
	if(!moveImg.style.top){
		moveImg.style.top="0px";
	}
	//通过parseInt来提取字符串中的数字
	var xpos=parseInt(moveImg.style.left);
	var ypos=parseInt(moveImg.style.top);
	var dist=0;
	// alert("aa");
	if(xpos==final_x&&ypos==final_y){
		return true;
	}
	if(xpos<final_x){
		dist=Math.ceil((final_x-xpos)/10);
		xpos+=dist;
	}else{
		dist=Math.ceil((xpos-final_x)/10);
		xpos-=dist;
	}

	if(ypos<final_y){
		dist=Math.ceil((final_y-ypos)/10);
		ypos+=dist;
	}else{
		dist=Math.ceil((ypos-final_y)/10);
		ypos-=dist;
	}

	//一定要记得改变位置后要把新的位置返还给style属性;
	//这是又要注意style属性值是字符串的,所以不要忘记加”px“
	moveImg.style.left=xpos+"px";
	moveImg.style.top=ypos+"px";
	//一定要注意在moveMessage中参数elementId是字符串,所以在做字符串拼接的时候一定要注意要额外为其添加
	//单引号以突出他是字符串,不然会出错
	var repeat="movement('"+elementId+"',"+final_x+","+final_y+","+interval+")";
	
	//这边最好把setTimeout返回值给保存在movement中,便于清除
	moveImg.movement1=setTimeout(repeat,interval);
}
addLoadEvent(prepareSlideShow);

****



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值