在前面的随笔中介绍了如何用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实现动画效果的更多相关文章

  1. 用js实现动画效果核心方式

    为了做好导航菜单,有时候需要在菜单下拉的时候实现动画效果,所以这几天就研究了研究如何用js实现动画效果,实现动画核心要用到两个函数,一个是setTimeOut,另一个是setInterval. 下边我 ...

  2. js实现动画效果框架

    RT,是参照慕课的教程做的.两个多小时的教程,看完了然后晚上的时候做了下,看的时候感觉明白了,但其实做的时候还是有很多小细节需要处理的. 上代码,思想什么的直接去慕课看教程就好了.点击这里 注释也比较 ...

  3. 二、JavaScript语言--JS实践--倒计时效果

    主要内容:分析不同倒计时效果的计算思路及方法,掌握日期对象Date,获取时间的方法,计算时差的方法,实现不同的倒时计效果. Javascript 日期对象: Date()返回当前的日期和时间 getY ...

  4. JS/JQ动画效果

    1.弹出框 <style> .mask { position: fixed; display: none; width: 100%; height: 100%; top: 0; left: ...

  5. 原生js动画效果(源码解析)

    在做页面中,多数情况下都会遇到页面上做动画效果,大部分都是用jquery来实现动画,今天正好看到一篇原生js实现动画效果的代码,特分享在此. 原文地址:http://www.it165.net/pro ...

  6. 如何使用SVG生成超酷的页面预加载素描动画效果

    在线演示 本地下载 1 SVG简介 可缩放矢量图形是基于可扩展标记语言(标准通用标记语言的子集),用于描述二维矢量图形的一种图形格式.它由万维网联盟制定,是一个开放标准. 2 SVG的特点 与其他图像 ...

  7. Vue过渡和动画效果展示(案例、GIF动图演示、附源码)

    前言 本篇随笔主要写了Vue过渡和动画基础.多个元素过渡和多个组件过渡,以及列表过渡的动画效果展示.详细案例分析.GIF动图演示.附源码地址获取. 作为自己对Vue过渡和动画效果知识的总结与笔记. 因 ...

  8. CSS动画效果的回调

    用纯JS实现动画效果代码量大,计算复杂.因此现在前端页面的动画效果一般都采用CSS来实现. CSS动画实现简单高效,但是在处理动画,控制动画过程上却缺少一些有效手段. 例如我们想在动画效果完成时调用回 ...

  9. Fiori里花瓣的动画效果实现原理

    Fiori里的busy dialog有两种表现形式,一种是下图里的花朵形状,由5个不断旋转的花瓣组成.另一种是下图的3/4个圆环不断旋转的效果. 关于前者的效果,可以看我制作的这个视频.这个视频是手动 ...

随机推荐

  1. C++流操作之fstream

    在Windows平台对文件进行存取操作可选的方案有很多,如果采用纯C,则需要用到File*等,当然也可以直接调用Windows API来做:如果采用C++,首先想到的就是文件流fstream.虽然在C ...

  2. docker 私有仓库上传镜像,其他docker服务器从私有镜像下载

    <pre name="code" class="cpp">docker:/data# docker ps CONTAINER ID IMAGE CO ...

  3. webpack入门笔记

    此为第一篇主要是webpack入门笔记: http://if-true.com/2015/10/16/webpack-tutorial-translate.html

  4. getopt()函数

    在讨论这个函数之前我们先理解两个概念:选项及其参数 gcc -o program program.c 在上述命令中 -o 就是其选项 program就是参数. getopt(): 头文件: #incl ...

  5. Java多线程-新特征-锁

    Java中读写锁有个接口java.util.concurrent.locks.ReadWriteLock,也有具体的实现ReentrantReadWriteLock,详细的API可以查看JavaAPI ...

  6. TCP/IP详解之:ICMP协议

    ICMP协议: ICMP是IP层的一个组成部分,ICMP报文是在IP数据报内部被传输的,用于在IP主机.路由器之间传递控制消息.控制消息是指网络不通.主机是否可达.路由是否可用等网络本身的消息.这些控 ...

  7. Ajax应用常见的HTTP ContentType设置

    文章出处:Ajax应用常见的HTTP ContentType设置 ajax开发中, 常遇到下面的几种情况: 1 服务端需要返回一段普通文本给客户端 2 服务端需要返回一段HTML代码给客户端 3 服务 ...

  8. 精读《javascript高级程序设计》笔记一——基本概念

    语法 严格模式 启用严格模式,在脚本顶部或函数内部上方添加"use strict";语句. 数据类型 typeof typeof返回undifined,boolean,number ...

  9. Javascript 匀速运动停止条件——逐行分析代码,让你轻松了解运动的原理

    我们先来看下之前的匀速运动的代码,修改了速度speed后会出现怎么样的一个bug.这里加了两个标杆用于测试 <style type="text/css"> #div1 ...

  10. php curl函数实例

    <?php function login(){ $url = 'http://jspatch.qq.com/offline/check?qver=6.2.0.427&hver=0& ...