记录一下封装运动函数的过程,这只是其中一种方法,并不代表它最好,但是我认为是比较好理解的
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.wrap{
width: 500px;
margin-left: 100px;
position: relative;
}
.l_line{
float: left;
width:2px;
height:200px;
background: black;
}
.box{
width:50px;
height: 50px;
background:red;
position:absolute;
left:0;
top:60px;
}
.r_line{
float: right;
width:2px;
height:200px;
background: black;
}
.btn{
position: absolute;
top:220px;
left:100px;
}
</style>
</head>
<body>
<div class="wrap">
<div class="l_line"></div>
<div class="box"></div>
<div class="r_line"></div>
<button class="btn">点击开始运动</button>
</div>
</body>
</html>
运动框架演变历史
//1 最初实现从左往右运动,后来考虑如果要在想下运动呢? 这时候在左右运动结束时在调用新的向下运动的函数,写完之后发现里面重复代码太多,所以把他封装起来
var oBox = document.querySelector('.box');
var oBtn = document.querySelector('.btn');
var speed = 5;
var target = 500;
var timer = null;
oBtn.onclick = function(){
timer = setInterval(function(){
var _left = oBox.offsetLeft;
oBox.style.left = _left + speed + 'px'
if(_left >= target - speed){
clearInterval(timer)
oBox.style.left = target + 'px';
fn()
}
},40)
}
function fn(){
timer = setInterval(function(){
var _top = oBox.offsetTop;
oBox.style.top = _top + speed + 'px'
console.log(_top)
if(_top >= target - speed){
clearInterval(timer)
oBox.style.top = target + 'px';
}
},40)
}
//2 现在是匀速运动,增加了回调函数来执行后面的运动
var oBox = document.querySelector('.box');
var oBtn = document.querySelector('.btn');
oBtn.onclick = function(){
animate(oBox,6,500,'left',sp)
}
function animate(ele,speed,target,attr,fn){
var timer = null;
timer = setInterval(function(){
var _attr = parseInt(getStyle(ele,attr));
if(_attr >= target - speed){
clearInterval(timer)
ele.style[attr] = target + 'px'
typeof fn === 'function' ? fn() : ''
}else{
ele.style[attr] = _attr + speed + 'px'
}
},40)
}
function sp(){
animate(oBox,4,200,'top')
}
function getStyle(ele,attr){
if(typeof getComputedStyle === 'function'){
return getComputedStyle(ele)[attr]
}else{
return ele.currentStyle[attr]
}
}
//3 改成了变速运动
var oBox = document.querySelector('.box');
var oBtn = document.querySelector('.btn');
oBtn.onclick = function(){
animate(oBox,2,500,'left',sp)
}
function animate(ele,ratio,target,attr,fn){
var timer = null;
ratio = ratio ? ratio : 6
timer = setInterval(function(){
var _attr = parseInt(getStyle(ele,attr));
var speed = (target - _attr)/ratio
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)
if(_attr >= target - speed){
clearInterval(timer)
ele.style[attr] = target + 'px'
typeof fn === 'function' ? fn() : ''
}else{
ele.style[attr] = _attr + speed + 'px'
}
},40)
}
function sp(){
animate(oBox,4,200,'top')
}
function getStyle(ele,attr){
if(typeof getComputedStyle === 'function'){
return getComputedStyle(ele)[attr]
}else{
return ele.currentStyle[attr]
}
}
//4 把参数换成对象形式
var oBox = document.querySelector('.box');
var oBtn = document.querySelector('.btn');
var options = {
ele:oBox,
ratio:2,
parameter:{
'left':500,
'top':200
}
}
var options1 = {
ele:oBox,
ratio:1,
parameter:{
'left':200,
}
}
oBtn.onclick = function(){
animate(options,sp)
}
function animate(options,fn){
clearInterval(options.timer)
options.ratio = options.ratio ? options.ratio : 6
options.timer = setInterval(function(){
var oB = true;
for(var i in options.parameter){
//元素当前属性值
var _attr = parseInt(getStyle(options.ele,i));
//目标点属性值
var target = options.parameter[i]
//计算速度
var speed = (target - _attr)/options.ratio ;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed) ;
options.ele.style[i] = _attr + speed + 'px'
if(_attr !== target){
oB = false;
}
}
if(oB){
clearInterval(options.timer)
typeof fn === 'function' ? fn() : ''
}
},40)
}
function sp(){
animate(options1)
}
function getStyle(ele,attr){
if(typeof getComputedStyle === 'function'){
return getComputedStyle(ele)[attr]
}else{
return ele.currentStyle[attr]
}
}
//5加上opacity
var oBox = document.querySelector('.box');
var oBtn = document.querySelector('.btn');
var options = {
ele:oBox,
ratio:4,
parameter:{
'left':500,
'opacity':0.7
}
}
var options1 = {
ele:oBox,
ratio:5,
parameter:{
'top':200,
'opacity':0.2
}
}
oBtn.onclick = function(){
animate(options,sp)
}
function animate(options,fn){
clearInterval(options.timer)
options.ratio = options.ratio ? options.ratio : 6
options.timer = setInterval(function(){
var oB = true;
for(var i in options.parameter){
if(i === 'opacity'){
//元素当前属性值
var _attr = getStyle(options.ele,i) * 100;
//目标点属性值
var target = options.parameter[i] * 100;
}else{
//元素当前属性值
var _attr = parseInt(getStyle(options.ele,i));
//目标点属性值
var target = options.parameter[i]
}
//计算速度
var speed = (target - _attr)/options.ratio ;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed) ;
if(i === 'opacity'){
options.ele.style.opacity = (_attr + speed) / 100;
options.ele.style.filter = "alpha(opacity =" + _attr + speed + ')';
}else{
options.ele.style[i] = _attr + speed + 'px'
}
if(_attr !== target){
oB = false;
}
}
if(oB){
clearInterval(options.timer)
typeof fn === 'function' ? fn() : ''
}
},40)
}
function sp(){
animate(options1)
}
function getStyle(ele,attr){
if(typeof getComputedStyle === 'function'){
return getComputedStyle(ele)[attr]
}else{
return ele.currentStyle[attr]
}
}