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个圆环不断旋转的效果. 关于前者的效果,可以看我制作的这个视频.这个视频是手动 ...
随机推荐
- poj1503---大数加法
先讲一种错误的做法:WA了n次,大神一定帮我看一下//看到有说数组大小开到250,我改了之后还是不//思路是将arr这个数组的每一行附上输入的值,然后求每列所有数之和,当然进位 //maxlen记录这 ...
- 初识Java--线程同步(2)
本文讲述Java中的线程同步和生产者消费者问题,其中主要涉及线程同步和wait().notify()方法的用法. wait和notify方法只能用在线程同步中,wait和notify是object的方 ...
- 【JavaScript脚本编程技术详解-----(一)】
首先说明,本系列教程是写给有一定的JavaScript编程基础的同学看的,最好还有其它的编程语言经验,因为里面可能涉及一些其它的程序设计语言写的源代码,这都是我自己总结的经验,我喜欢在学习一门新的编程 ...
- javascript高级知识点——指定上下文实现
代码信息来自于http://ejohn.org/apps/learn/. 当我们将一个对象的点击事件绑定到一个事件触发元素时会发生什么? <ul id="results"&g ...
- 修改SharePoint平台登录者显示名称
protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { //提升权限,拿系统服务帐号来执行此段代码 ...
- AngularJs 实例
1.AngularJs 表单验证: 示例 .controller('signupController', ['$scope', function($scope) { $scope.submitted ...
- bat文件自动编译InnoSetup脚本
今天想制作一个bat文件,打包多个innosetup脚本,参考链接:http://www.cnblogs.com/joean/p/4870428.html 流程: 新建文本文档,将.txt改为.bat ...
- C#委托,事件,匿名委托
作为一个初学者,写下来是当做自己的学习笔记,希望在以后遇到问题的时候能够快速的找到方法 如果能帮助跟我一样的新人是更好不过的了 如果有什么不正确或者可以改进的地方也希望大家能够指出来 ...
- windows7 64位下运行 regsvr32 注册ocx或者dll的方法
来源:转载 it won't work for you unless you have some form of Visual Basic tools loaded on your system: ...
- oc swift 混编 特技
1.swift 工程新建oc文件,新建的时候提示是否桥接文件,点击yes,把swift要用的oc文件的头文件 都导入桥接文件中就OK了. 2.在swift工程中oc调用 swift文件,需要在导入名字 ...