JavaScript之JS实现动画效果
在前面的随笔中介绍了如何用DOM技术修改文档的央样式信息,用JavaScript添加样式信息可以节约我们的时间和精力,但总的来说,CSS仍是完成这类任务的最佳工具。但是有一个应用领域是目前的CSS无能为力的。如果我们想随着时间的变化而不断改变某个元素的样式,则只能用JavaScript。JavaScript能够按照预定的时间间隔重复的调用一个函数,而意味着我们可以随着时间的推移而不断改变某个元素的样式。
动画是样式随着时间变化的完美例子之一。简单的说,动画就是让元素的位置随着时间而不断的发生变化。下面来说下使用JavaScript动画,必须要掌握的几个HTML的基本知识:
一、位置
网页元素在浏览器窗口中的位置是一种表示性的信息。因此,位置信息通常使用CSS负责设置的。下面这段CSS代码对某个元素在网页上的位置做了预定:
element{
position:absolute;
top:50px;
left:100px;
}
position属性的合法值有static、absolute、relative、fixed四种。
1、static是position属性的默认值,意思是有关元素将按照它们在标记里出现的先后顺序出现在浏览器窗口里。
2、relative的含义与static相似,区别是postion属性为relative的元素还可以(通过应用float属性)从文档的正常显示顺序中脱离出来。
3、如果一个元素的position属性设为absolute时,我们就可以把它摆到容纳它的"容器"的任何位置。这个容器要么是文档本身,要么是一个有着fixed或absolute属性的父元素。他的显示位置由top、left、right、bottom四个属性决定和他本身在文档中的位置无关。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<style type="text/css">
</style>
</head>
<body>
<p id="message">Whee!</p><!--(使兴奋,使激动,啊)!-->
<script type="text/javascript">
//通过js来设置<p>标签的初试显示位置
function positionMessage() {
if (!checkCompatibility) return;
var ele = document.getElementById("message");
ele.style.position = "absolute";
ele.style.top = "100px";
ele.style.left = "50px";
}
//通过style属性改变<p>标签的显示位置
function moveMessage() {
var ele = document.getElementById("message");
ele.style.left = "200px";
}
var loadeventlist = [positionMessage, moveMessage];
addOnloadEventlist(loadeventlist);
//给window.onload事件绑定函数数组 这个函数数组将在页面全部加在完毕之后被调用
function addOnloadEventlist(eventlist) {
if (!eventlist) return false;
var oldonload = window.onload;
window.onload = function () {
for (var i = 0; i < eventlist.length; i++) {
eventlist[i]();
}
}
}
//检查浏览器对DOM方法的支持
function checkCompatibility() {
if (!document.getElementById) return false;
if (!document.createElement) return false;
if (!document.createTextNode) return false;
if (!document.getElementsByTagName) return false;
if (!document.getElementsByName) return false;
return true;
} </script>
</body>
</html>
上面这段代码,我们看不到任何动画效果,因为我们的JavaScript太有效率了;函数一个接一个的执行.期间根本没有我们能察觉的间隔。
所以为了实现动画效果,我们必须创造出时间间隔来,而这正是实现动画效果的关键!所以我们来说下时间动画效果的第二个要素时间!
二、时间
1、setTimeut()函数 他能够让某个函数在经过一段预定的时间之后才开始执行。这个函数有两个参数:第一个参数是一个字符串,其内容是将要执行的那个函数的名字。第二个参数是一个数值,他以毫秒为单位设定了需要经过多长时间才开始执行第一个参数所给出的函数。
setTimeout("functionExample",interval) //interval时间间隔 是一个数值
但是这样写名称为functionExample的函数,将会一直被调用而不会停止,所以正确的代码应该这样写,除非你是打算让他一直被调用!
var para=setTimeout(" ",interval);
这样将把对functionExample函数的调用赋值给para变量,这样如果我们想取消正在排队等待执行的函数,就可以这样做
clearTimeout(para);
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<p id="message">Whee!</p><!--(使兴奋,使激动,啊)!-->
<script type="text/javascript">
//通过js来设置<p>标签的初试显示位置
function positionMessage() {
if (!checkCompatibility) return;
var ele = document.getElementById("message");
ele.style.position = "absolute";
ele.style.top = "50px";
ele.style.left = "50px";
}
//通过style属性改变<p>标签的显示位置
function moveMessage() {
var ele = document.getElementById("message");
var xpos = parseInt(ele.style.left);
var ypos = parseInt(ele.style.top);
if (xpos == 200 && ypos == 100) {
return true;
}
if (xpos < 100) {
xpos++;
}
if (xpos > 100) {
xpos--;
}
if (ypos > 100) {
ypos--;
}
if (ypos < 100) {
ypos++;
}
ele.style.left = xpos + "px";
ele.style.top = ypos + "px";
movement=setTimeout("moveMessage()", 6);
}
var loadeventlist = [positionMessage, moveMessage];
addOnloadEventlist(loadeventlist);
//给window.onload事件绑定函数数组 这个函数数组将在页面全部加在完毕之后被调用
function addOnloadEventlist(eventlist) {
if (!eventlist) return false;
var oldonload = window.onload;
window.onload = function () {
for (var i = 0; i < eventlist.length; i++) {
eventlist[i]();
}
}
}
//检查浏览器对DOM方法的支持
function checkCompatibility() {
if (!document.getElementById) return false;
if (!document.createElement) return false;
if (!document.createTextNode) return false;
if (!document.getElementsByTagName) return false;
if (!document.getElementsByName) return false;
return true;
} </script>
</body>
</html>
上面这段代码完美的实现了我们想要实现的动画效果,通过每次移动一点位置和setTimeout()函数配合,实现了这个效果,代码观察代码发现上面这段代码还可以优化,让它变得更加的通用!因为所有这些信息都是硬编码在函数代码里。元素只能移动到固定的位置,而且两次移动之间的时间也是固定的!如果把这些常量都改为变量,这个函数的通用性和灵活性将会大大增加。下面的代码将会对上面这段代码进行抽象!
下面是分析上面那个函数后总结出新函数可能变化的东西,然后把它作为变量,交给使用者赋值,增加函数的通用性和灵活性
1、打算移动的元素ID
2、元素移动终点的横坐标
3、元素移动终点的纵坐标
4、每次元素移动所产生的时间间隔
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head>
<body>
<p id="message">
Whee!</p>
<!--(使兴奋,使激动,啊)!-->
<script type="text/javascript">
//通过js来设置<p>标签的初试显示位置
function positionMessage() {
if (!checkCompatibility) return;
var ele = document.getElementById("message");
ele.style.position = "absolute";
ele.style.top = "100px";
ele.style.left = "50px";
moveElement("message",200,100,5);
}
function moveElement(elementID, final_x, final_y, interval) {
//下面是每次调用这个新函数可能变化的东西
//1、打算移动的元素ID -elementID
//2、元素移动终点的横坐标 -final_x
//3、元素移动终点的纵坐标 -final_y
//4、每次元素移动所产生的时间间隔 interval
//为上面的变化的东西取个描述性的名字便于理解
if (!document.getElementById(elementID)) { return false; }
else { var ele = document.getElementById(elementID); }
var xpos = parseInt(ele.style.left);
var ypos = parseInt(ele.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++;
}
ele.style.left = xpos + "px";
ele.style.top = ypos + "px";
var repeat = "moveElement('" + elementID + "','" + final_x + "','" + final_y + "','" + interval + "')";
movement = setTimeout(repeat, interval);
}
var loadeventlist = [positionMessage];
addOnloadEventlist(loadeventlist);
//给window.onload事件绑定函数数组 这个函数数组将在页面全部加在完毕之后被调用
function addOnloadEventlist(eventlist) {
if (!eventlist) return false;
var oldonload = window.onload;
window.onload = function () {
for (var i = 0; i < eventlist.length; i++) {
eventlist[i]();
}
}
}
//检查浏览器对DOM方法的支持
function checkCompatibility() {
if (!document.getElementById) return false;
if (!document.createElement) return false;
if (!document.createTextNode) return false;
if (!document.getElementsByTagName) return false;
if (!document.getElementsByName) return false;
return true;
} </script>
</body>
</html>
这段代码相比与上面那段代码,代码的灵活度和通用度,明显提高了!
下面我们就用封装好的moveElement函数做一个常用的网页特效demo
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style type="text/css">
#slideshow
{
width:100px;
height:100px;
position:relative;
overflow:hidden;
}
</style>
</head>
<body>
<h1>
Web Design</h1>
<p>
These are things you should know</p>
<ol id="linklist">
<li><a href="#">Structure</a></li>
<li><a href="#">Presentation</a></li>
<li><a href="#">Behavior</a></li>
</ol>
<div id="slideshow">
<img id="preview" alt=" " src="../img/topic.png" />
</div>
<script type="text/javascript">
function prepareSlideshow() {
if (!checkCompatibility()) return false;
if (!document.getElementById("linklist")) return false;
if (!document.getElementById("slideshow")) return false;
var preview = document.getElementById("preview"); //获取预览图片的div
preview.style.position = "absolute";
preview.style.left = "0px";
preview.style.top = "0px";
var list = document.getElementById("linklist");
var links = list.getElementsByTagName("a");
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);
}
} function moveElement(elementID, final_x, final_y, interval) {
//下面是每次调用这个新函数可能变化的东西
//1、打算移动的元素ID -elementID
//2、元素移动终点的横坐标 -final_x
//3、元素移动终点的纵坐标 -final_y
//4、每次元素移动所产生的时间间隔 interval
//为上面的变化的东西取个描述性的名字便于理解
if (!document.getElementById(elementID)) { return false; }
else { var ele = document.getElementById(elementID); }
var xpos = parseInt(ele.style.left);
var ypos = parseInt(ele.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++;
}
ele.style.left = xpos + "px";
ele.style.top = ypos + "px";
var repeat = "moveElement('" + elementID + "','" + final_x + "','" + final_y + "','" + interval + "')";
movement = setTimeout(repeat, interval);
}
function checkCompatibility() {
if (!document.getElementById) return false;
if (!document.createElement) return false;
if (!document.createTextNode) return false;
if (!document.getElementsByTagName) return false;
if (!document.getElementsByName) return false;
return true;
}
function addOnloadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != "function") {
window.onload = func; //如果window.onload事件没有绑定任何function则正常绑定
}
else {
//如果window.onload事件已经绑定了函数,则在原来的基础上,继续添加新的函数
window.onload = function () {
oldonload();
func();
};
}
}
addOnloadEvent(prepareSlideshow);
</script>
</body>
</html>
代码中的那张图片是:

上面这段代码实现的特效的是:当鼠标放到超链接上,就能以动画的效果显示对应的字母。
效果很酷,但是代码存在一点小瑕疵,这点我们经常容易忽视,问题就是,当我们把鼠标指针在链接之间快速的来回移动,动画效果将变得混乱起来。
JavaScript之JS实现动画效果的更多相关文章
- 用js实现动画效果核心方式
为了做好导航菜单,有时候需要在菜单下拉的时候实现动画效果,所以这几天就研究了研究如何用js实现动画效果,实现动画核心要用到两个函数,一个是setTimeOut,另一个是setInterval. 下边我 ...
- js实现动画效果框架
RT,是参照慕课的教程做的.两个多小时的教程,看完了然后晚上的时候做了下,看的时候感觉明白了,但其实做的时候还是有很多小细节需要处理的. 上代码,思想什么的直接去慕课看教程就好了.点击这里 注释也比较 ...
- 二、JavaScript语言--JS实践--倒计时效果
主要内容:分析不同倒计时效果的计算思路及方法,掌握日期对象Date,获取时间的方法,计算时差的方法,实现不同的倒时计效果. Javascript 日期对象: Date()返回当前的日期和时间 getY ...
- JS/JQ动画效果
1.弹出框 <style> .mask { position: fixed; display: none; width: 100%; height: 100%; top: 0; left: ...
- 原生js动画效果(源码解析)
在做页面中,多数情况下都会遇到页面上做动画效果,大部分都是用jquery来实现动画,今天正好看到一篇原生js实现动画效果的代码,特分享在此. 原文地址:http://www.it165.net/pro ...
- 如何使用SVG生成超酷的页面预加载素描动画效果
在线演示 本地下载 1 SVG简介 可缩放矢量图形是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式.它由万维网联盟制定,是一个开放标准. 2 SVG的特点 与其他图像 ...
- Vue过渡和动画效果展示(案例、GIF动图演示、附源码)
前言 本篇随笔主要写了Vue过渡和动画基础.多个元素过渡和多个组件过渡,以及列表过渡的动画效果展示.详细案例分析.GIF动图演示.附源码地址获取. 作为自己对Vue过渡和动画效果知识的总结与笔记. 因 ...
- CSS动画效果的回调
用纯JS实现动画效果代码量大,计算复杂.因此现在前端页面的动画效果一般都采用CSS来实现. CSS动画实现简单高效,但是在处理动画,控制动画过程上却缺少一些有效手段. 例如我们想在动画效果完成时调用回 ...
- Fiori里花瓣的动画效果实现原理
Fiori里的busy dialog有两种表现形式,一种是下图里的花朵形状,由5个不断旋转的花瓣组成.另一种是下图的3/4个圆环不断旋转的效果. 关于前者的效果,可以看我制作的这个视频.这个视频是手动 ...
随机推荐
- rsyslog 日志服务器端配置
$EscapeControlCharactersOnReceive off #关闭rsyslog默认转译ASCII<32的所有怪异字符,包括换行符等 $template tocFormat,&q ...
- java线程管理
java线程管理 参见: http://harmony.apache.org/subcomponents/drlvm/TM.html 1. 修订历史 2. 关于本文档 2.1. 目的 2.2. 面向的 ...
- objective-c 可变参数
容易发现Cocoa Foundation 中提供了一些可变参数的方法,如: NSLog(NSString *format, ...) 在实际的编程实践中,我们也需要自己实现可变参数的方法.在Objc中 ...
- Struts2 二、为Action的参数注入值
为Action参数注入值,主要使用在的场景为,Action的一个参数的值不是固定的是可以改变的,所以不能直接写在Action中,可以通过Struts配置的方式将值配置到Struts中,然后通过注入的方 ...
- 构建一个用于产品介绍的WEB应用
为了让用户更好地了解您的产品功能,您在发布新产品或者升级产品功能的时候,不妨使用一个产品介绍的向导,引导用户熟悉产品功能和流程.本文将给您介绍一款优秀的用于产品介绍的WEB应用. 就像微博或邮箱这类W ...
- HTML5 元素拖放
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 文件和文件夹权限-Win7公共盘中出现大量临时文件
公司中有一个文件服务器,给不同部门和员工设置了不同的权限,最近有员工(没有修改权限,有读取及执行,读取,写入)反映在公共盘上修改文件的时候会产生大量的临时文件,添加上修改权限之后就可以了,然后被同事问 ...
- java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/LoopTag
异常原因:缺少jstl.jar包.一般在新建Web项目是jstl一项不要选none就不会出现这个问题.(还有可能就是缺少servlet-api.jar)
- C# 懒人常用异步方法
Winform this.Invoke(new Action(() => { })); Wpf this.Dispatcher.Invoke(DispatcherPriority.Normal, ...
- lightoj 1408 Batting Practice
题意:一个人若连续进k1个球或连续不进k2个球,游戏结束,给出这个人进球的概率p,求到游戏结束时这个投球个数的期望. 进球概率为p,不进概率 q=1-p 设 f[i] 表示连续 i 次不进距离连续k2 ...