《JavaScript DOM编程艺术》笔记:用js实现动画效果(八)

  • 位置

  • CSS
/*把element元素摆放在距离浏览器窗口的左边界100像素,距离浏览器窗口的上边界50像素的位置上。*/
element {
	position: absolute;
	top:50px;
	left:100px;
}
  • DOM
element.style.position = "absolute";
element.style.left = "100px";
element.style.top = "50px";

position属性的合法值有static、fixed、relative、absolute四种。static是position属性的默认值,意思是有关元素将按照它们在标记里出现的先后顺序出现在浏览器窗口里。relative的含义与static相似,区别是position属性等于relative的元素还可以(通过应用float属性)从文档的正常显示顺序里脱离出来。

如果把某个元素的position属性设置为absolute,我们就可以把它摆放到容纳它的容器的任何位置。这个容器要么是文档本身,要么是一个有着fixed或absolute属性的父元素。这个元素在原始标记里出现的位置与它的显示为位置无关,因为他的显示由top,left,right和botton等属性决定。你可以使用像素或百分比作为单位设置这些属性的值。

<p id="message">Whee!</p>
function positionMessage() {
	if(!document.getElementById) return false;
	if(!document.getElementById("message")) return false;
	var elem = document.getElementById("message");
	elem.style.position = "absolute";
	elem.style.left = "50px";
	elem.style.top = "100px";
	// body...
}
addLoadEvent(positionMessage);

  • 时间

js函数setTimeout能够让某个函数在经历过一段预定的时间之后才开始执行。这个函数带有两个参数:第一个参数通常是一个字符串,其内容是将要执行的那个函数的名字;第二个参数是一个数值,它以毫秒为单位设定了需要经过多长时间后开始执行第一个参数所给出的函数:

setTimeout("function",interval)

在绝大多数时候,把这个函数调用赋值给一个变量将是一个好主意:

variable = setTimeout("function",interval)

如果想要取消某个正在排队等待执行的函数,就必须事先像上面这样把setTimeout函数返回值赋值给一个变量。你可以用一个clearTimeout的函数来取消等待执行队列里的某个函数。这个函数需要一个参数-----保存着某个setTimeout函数调用返回值得变量:

clearTimeout(variable)

修改positionMessage函数,让它5秒之后再去调用moveMessage函数:

function positionMessage() {
	if(!document.getElementById) return false;
	if(!document.getElementById("message")) return false;
	var elem = document.getElementById("message");
	elem.style.position = "absolute";
	elem.style.left = "50px";
	elem.style.top = "100px";
	movement = setTimeout("moveMessage()",500);
	// body...
}

function moveMessage(){
	var elem = document.getElementById("message");
	elem.style.left = "200px"
}
addLoadEvent(positionMessage);
  • 时间递增

function positionMessage() {
	if(!document.getElementById) return false;
	if(!document.getElementById("message")) return false;
	var elem = document.getElementById("message");
	elem.style.position = "absolute";
	elem.style.left = "50px";
	elem.style.top = "100px";
	movement = setTimeout("moveMessage()",10);
	// body...
}

function moveMessage(){
	var elem = document.getElementById("message");
	//获得元素的当前位置
	var xpos = parseInt(elem.style.left);
	var ypos = parseInt(elem.style.top);
	if(xpos == 200 && ypos == 100)
	{
		return true;
	}
	if(xpos <200)
	{
		xpos++;
	}
	if(xpos> 200)
	{
		xpos--;
	}
	if(ypos <100)
	{
		ypos ++;
	}
	if(ypos >100)
	{
		ypos --;
	}

	
	elem.style.left =xpos+ "px";
	elem.style.top =ypos+ "px";
	movement = setTimeout("moveMessage()",10);
}
addLoadEvent(positionMessage);

函数抽象化

function positionMessage() {
	if(!document.getElementById) return false;
	if(!document.getElementById("message")) return false;
	var elem = document.getElementById("message");
	elem.style.position = "absolute";
	elem.style.left = "50px";
	elem.style.top = "100px";
	//movement = setTimeout("moveMessage()",10);
	moveElement("message",200,100,10);
	// body...
}
function moveElement(elementID,final_x,final_y,interval){
	var elem = document.getElementById(elementID);
	//获得元素的当前位置
	var xpos = parseInt(elem.style.left);
	var ypos = parseInt(elem.style.top);
	if(xpos == final_x && ypos == final_y)
	{
		return true;
	}
	if(xpos <final_x)
	{
		xpos++;
	}
	if(xpos> final_x)
	{
		xpos--;
	}
	if(ypos <final_y)
	{
		ypos ++;
	}
	if(ypos >final_y)
	{
		ypos --;
	}

	
	elem.style.left =xpos+ "px";
	elem.style.top =ypos+ "px";
	var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
	movement = setTimeout(repeat,interval);
}


addLoadEvent(positionMessage);
  • onmouseover事件显示图片

<!DOCTYPE html>
<html lang = "en">
 <head>
 <meta charset = "utf-8"/>
 <title>Web Design</title>
<!--  <link rel="stylesheet" href="layout.css" media="screen"/> -->
 </head>
 <body>
 	<h1>Web Design</h1>
   <p>There are the things you shoule know.</p>
 	<ol id="linklist">
 	<li>
 		<a href="image/btn_acomlete_1.png">Firework</a>
 	</li>
 	 <li>
 		<a href="image/btn_acomlete_2.png">tea</a>
 	</li>
  	<li>
 		<a href="image/btn_allcomlete_1.png">Rose</a>
 	</li>
 	<li>
 		<a href="image/btn_allcomlete_2.png">Big bar</a>
 	</li> 
   <img src="image/test.gif" alt = "building blocks of web design" id="preview"/>
 	
 	</ol>	

   <script>
   </script> 
 </body>
</html>

现在是整张图可见,若要实现每次显示一部分,要用css实现

CSS的overflow属性用来处理一个元素的尺寸超出其容器尺寸的情况。当一个元素包含的内容超出自身的大小时,就会发生内容溢出,这种情况,你可以对内容进行剪裁,只让一部分内容可见。你还可以通过overflow属性告诉浏览器是否需要显示滚动条,以便让用户能够看到内容的其余部分。

overflow属性的可取值有4种:visible、hidden、scroll、和auto

visible:不裁剪溢出的内容。浏览器将把溢出的内容呈现在其容器元素的显示区域以外,全部内容都可见。

hidden:隐藏溢出的内容。内容只显示在其容器元素的显示区域里,这意味着只有一部分内容可见。

scroll:类似于hidden,浏览器将对溢出内容进行隐藏,但显示一个滚动条以方便用户能够滚动看到内容的其他部分。

auto:类似于scroll,但浏览器只在确定发生溢出时才显示滚动条。如果内容没有溢出,就不显示滚动条。

   <!-- 首先把这张图放在一个容器元素 -->
   <div id="slideshow">
      <img src="image/test.gif" alt = "building blocks of web design" id="preview"/>
   </div>
#slideshow{
	width:100px;
	height: 100px;
	position: relative;
	/*把position设为relative很重要,因为我们想让图片使用绝对位置。通过使用值relative,子元素的(0,0)坐标将固定在slidenshow div的左上角*/
	overflow: hidden;
	/*将overflow设为hidden确保其中的内容会被剪裁*/
}

JS

我们计划用moveElement函数来移动图片。根据用户正把鼠标悬停在哪个连接上,我们将这个图片向左或向右移动。

我们需要把调用moveElement函数的行为,与链接清单里每一个链接的onmouseover事件关联起来。

编写一个prepareSlideshow函数来完成这项工作

function prepareSlideshow() {
	//确保浏览器支持DOM方法
	if(!document.getElementsByTagName) return false;
	if(!document.getElementById) return false;
	//确保元素存在
	if(!document.getElementById("linklist")) return false;
	if(!document.getElementById("preview")) return false;
	//为图片应用样式
	var preview = document.getElementById("preview");
	preview.style.position = "absolute";
	preview.style.left = "0px";
	preview.style.top = "0px";
	//取得列表中的所有链接
	var list = document.getElementById("linklist");
	var links = list.getElementsByTagName("a");
	//为mouseover事件添加动画效果
	links[0].onmouseover = function(){
		moveElement("preview",-100,0,10);
	}
	links[1].onmouseover = function(){
		moveElement("preview",-200,0,10);
	}
	links[2].onmouseover = function(){
		moveElement("preview",-300,0,10);
	}
	links[3].onmouseover = function(){
		moveElement("preview",-400,0,10);
	}
	// body...
}

这留下了一个隐患:每当用户把鼠标指针悬停在某个链接上,不管上一次调用是否已经把图片移动到位,moveElement函数都会被再次调用并试图把这个图片移动到另一个地方去。于是,当用户在链接之间快速移动鼠标时,movement变量就会像一条拔河绳那样来回变化,而moveElement函数会试图把图片同时移动到两个不同的地方去。

如果用户移动鼠标的速度够快,累积在setTimeout队列里的事件就会导致动画效果产生滞后。为了消除动画滞后的现象,可以用clearTimeout(movement)

可是,如果在还没有设置movement变量之前就执行这条语句,会报错。

function moveElement(elementID,final_x,final_y,interval){
	var elem = document.getElementById(elementID);
	//******
	if(elem.movement)
	{
		clearTimeout(elem.movement);
	}
	//获得元素的当前位置
	var xpos = parseInt(elem.style.left);
	var ypos = parseInt(elem.style.top);
	if(xpos == final_x && ypos == final_y)
	{
		return true;
	}
	if(xpos <final_x)
	{
		xpos++;
	}
	if(xpos> final_x)
	{
		xpos--;
	}
	if(ypos <final_y)
	{
		ypos ++;
	}
	if(ypos >final_y)
	{
		ypos --;
	}

	
	elem.style.left =xpos+ "px";
	elem.style.top =ypos+ "px";
	var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
	elem.movement = setTimeout(repeat,interval);//******
}
  • 改进动画效果

function moveElement(elementID,final_x,final_y,interval){
	var elem = document.getElementById(elementID);
	//******
	if(elem.movement)
	{
		clearTimeout(elem.movement);
	}
	//获得元素的当前位置
	var xpos = parseInt(elem.style.left);
	var ypos = parseInt(elem.style.top);
	if(xpos == final_x && ypos == final_y)
	{
		return true;
	}
	if(xpos <final_x)
	{
		dist = Math.ceil((final_x - xpos)/10)
		xpos = xpos + dist;
	}
	if(xpos> final_x)
	{
	    dist = Math.ceil((xpos- final_x )/10)
		xpos = xpos - dist;
	}
	if(ypos <final_y)
	{
		ypos ++;
	}
	if(ypos >final_y)
	{
		ypos --;
	}

	
	elem.style.left =xpos+ "px";
	elem.style.top =ypos+ "px";
	var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
	elem.movement = setTimeout(repeat,interval);//******
}

添加安全监察

	if(!elem.style.left)
	{
		elem.style.left = "0px";
	}
	if(!elem.style.top)
	{
		elem.style.top = "0px";
	}

生成HTML标记

文档中包含一些只是为了能够用javascript代码实现动画效果而存在的标记。

如果用户没有启动js支持,以上内容未免有些多余。

function prepareSlideshow() {
	//确保浏览器支持DOM方法
	if(!document.getElementsByTagName) return false;
	if(!document.getElementById) return false;
//*************************
	if(!document.getElementById("linklist")) return false;
	var slideshow = document.createElement("div");
	slideshow.setAttribute("id","slideshow");

	var preview = document.createElement("img");
	preview.setAttribute("src","image/test.gif");
	preview.setAttribute("alt","building blocks of web design");
	preview.setAttribute("id","preview");
	slideshow.appendChild(preview);

	var list = document.getElementById("linklist");
	insertAfter(slideshow,list);
//*************************
	var links = list.getElementsByTagName("a");
	//为mouseover事件添加动画效果
	links[0].onmouseover = function(){
		moveElement("preview",-100,0,10);
	}
	links[1].onmouseover = function(){
		moveElement("preview",-200,0,10);
	}
	links[2].onmouseover = function(){
		moveElement("preview",-300,0,10);
	}
	// body...
}
function insertAfter(newElement,targetElement)
{
	var parent = targetElement.parentNode;
	if(parent.lastChild == targetElement)
	{
		parent.appendChild(newElement);
	}
	else
	{
		parent.insertBefore(newElement,targetElement.nextSibling);

	}
}
#slideshow{
	width:100px;
	height: 100px;
	position: relative;
	/*把position设为relative很重要,因为我们想让图片使用绝对位置。通过使用值relative,子元素的(0,0)坐标将固定在slidenshow div的左上角*/
	overflow: hidden;
	/*将overflow设为hidden确保其中的内容会被剪裁*/
}

#preview{
	position: absolute;
}
<!DOCTYPE html>
<html lang = "en">
 <head>
 <meta charset = "utf-8"/>
 <title>Web Design</title>
 <link rel="stylesheet" href="layout.css" media="screen"/>
 </head>
 <body>
 	<h1>Web Design</h1>
   <p>There are the things you shoule know.</p>
 	<ol id="linklist">
 	<li>
 		<a href="image/btn_acomlete_1.png">Firework</a>
 	</li>
 	 <li>
 		<a href="image/btn_acomlete_2.png">tea</a>
 	</li>
  	<li>
 		<a href="image/btn_allcomlete_1.png">Rose</a>
 	</li>
   <!-- 首先把这张图放在一个容器元素 -->
 	</ol>	

   <script src = "example.js">
   </script> 
 </body>
</html>

猜你喜欢

转载自blog.csdn.net/baidu_29474379/article/details/84142428