javascript dom编程艺术学习笔记之实现动画效果
@(JavaScript)[学习笔记]
1.动画基础知识
动画是让元素的位置随时间的变化不断变化
1.1 位置
假定有个id为message的元素,可以用javascript来设置这个属性的位置positionMessage()
也可以用javascript来改变元素的位置"moveMessage()"
页面加载时,两个函数几乎同时运行,肉眼看不到变化,位置就改变了,无法实现动画效果
1.2 时间
可以用setTimeout("function", interbal)
函数
第一个参数是函数名
第二个参数是延时时间,单位毫秒
取消函数clearTimeout(variable)
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()" , 5000)
}
movement是一个全局变量。可以在该函数以外任意位置取消跳跃
1.3 时间递增量
更新moveMessage函数,让元素以渐变方式移动
- 获取元素的位置
- 如果元素到达目的地,则退出这个函数
- 如果尚未到达,向目的地移动
- 经过一段时间间隔,重复步骤一
JavaScript函数parseInt
可以把字符串数值提取出来
用parseFloaat
函数可以提取浮点数
1.4 抽象
编写moveElement函数
function moveElement(elementID,final_x,final_y,interval) {
if (!document.getElementById) return false;
if (!document.getElementById(elementID)) return false;
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);
}
1.5 使用moveElement函数
moveElement("mwssage", 200, 100, 10);
2. 实用的动画
动画元素易引起用户反感,除非浏览器允许用户“冻结”移动的内容,否则就应该避免内容在页面中移动
2.1 提出问题
有一个包含一些列链接的网页,用户鼠标悬停某个链接,用先睹为快的方式告诉用户链接去往何处,可以展示一张预览图片
标记语言如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Web Design</title>
<style type="text/css" media="screen">
@import url(styles/layout.css);
</style>
<script type="text/javascript" src="scripts/addLoadEvent.js">
</script>
<script type="text/javascript" src="scripts/moveElement.js">
</script>
<script type="text/javascript" src="scripts/prepareSlideshow.js">
</script>
</head>
<body>
<h1>Web Design</h1>
<p>These are the things you should know.</p>
<ol id="linklist">
<li>
<a href="structure.html">Structure</a>
</li>
<li>
<a href="presentation.html">Presentation</a>
</li>
<li>
<a href="behavior.html">Behavior</a>
</li>
</ol>
<div id="slideshow">
<img src="topics.gif" alt="building blocks of web design" id="preview" />
</div>
</body>
2.3 CSS
overflow属性处理元素尺寸超过容器的情况。
overflow可取属性有四种:visible,hidden,scroll,auto
- visible:不裁减溢出内容
- hidden:隐藏溢出内容
- scroll:隐藏溢出内容,但有一个滚动条
- auto:发生溢出时才有滚动条,无溢出不滚动
2.4 JavaScript
function prepareSlideshow() {
// Make sure the browser understands the DOM methods
if (!document.getElementsByTagName) return false;
if (!document.getElementById) return false;
// Make sure the elements exist
if (!document.getElementById("linklist")) return false;
var slideshow = document.createElement("div");
slideshow.setAttribute("id","slideshow");
var preview = document.createElement("img");
preview.setAttribute("src","topics.gif");
preview.setAttribute("alt","building blocks of web design");
preview.setAttribute("id","preview");
slideshow.appendChild(preview);
var list = document.getElementById("linklist");
insertAfter(slideshow,list);
// Get all the links in the list
var links = list.getElementsByTagName("a");
// Attach the animation behavior to the mouseover event
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);
}
}
addLoadEvent(prepareSlideshow);
2.5 变量作用域问题
如果把鼠标在链接间快速移动,动画效果会变得很混乱
这是由全局变量引起的,在抽象化过程,未对变量movement做任何修改
存在与特定元素有关的变量,就是属性
function moveElement(elementID,final_x,final_y,interval) {
if (!document.getElementById) return false;
if (!document.getElementById(elementID)) return false;
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);
}
如果函数执行时已经有movement属性,就用clearTimeout对其复位,这样就只执行一条函数调用语句
2.6 改进动画效果
让过度更平滑一些,每次移动十分之一
dist = (final_x - dlist)/10;
xpos = xpos + dlist;
Math对象的ceil方法:返回不小于结果值的一个整数
Math对象的floor方法:返回大于结果值的一个整数
Math对象的round方法:返回与之最接近的一个整数
2.7 添加安全检查
var xpos = parseInt(elem.style.left);
var ypos = parseInt(elem.style.top);
这里有一个假设,必须有left和top属性
方法一:
if (!elem.stytle.left || !elem.stytle.top) return false;
方法二:
if (!elem.stytle.left){
elem.stytle.left = "0px";
}
if (!elem.stytle.top){
elem.stytle.top = "0px";
}
2.8 生成HTML标记
- 创建div元素
- 创建img元素
- 把img元素加入div子元素