1.简单的运动:
html布局:
<style>
.box{
width: 100px;
height: 100px;
background: pink;
position:absolute;
left: 0;
top: 0;
}
</style>
<div class="box"></div>
js代码:
var box = document.querySelector(".box");
// 点击div让div向右移动200px
box.onclick=function(){
// 获取当前样式
var currentStyle = window.getComputedStyle(box)["left"];
// 获取到的是字符串,转为数字
currentStyle = parseInt(currentStyle);
// 设置定时器,让当前样式每隔20毫秒增加5px
var timer = setInterval(function(){
currentStyle += 5;
// 判断增加后的样式是否到达指定距离
if(currentStyle >= 200){
// 指定增加后的样式的最大值
currentStyle = 200;
// 清除定时器
clearInterval(timer);
}
// 将增加后的样式重新设置到元素上
box.style.left = currentStyle + 'px';
},20);
}
2.将运动封装为函数:
var box = document.querySelector(".box");
// 点击div让div向右移动到200px
box.onclick=function(){
sport(box,"left",200)
}
/*
* @ ele 要运动的元素对象
* @ attr 要运动css属性
* @ target 运动的目标位置
*/
function sport(ele,attr,target){
// 获取当前样式
var currentStyle = window.getComputedStyle(ele)[attr];
// 获取到的是字符串,转为数字
currentStyle = parseInt(currentStyle);
// 设置定时器,让当前样式每隔20毫秒增加5px
var timer = setInterval(function(){
currentStyle += 5;
// 判断增加后的样式是否到达指定距离
if(currentStyle >= target){
// 清除定时器
clearInterval(timer);
}else{
// 将增加后的样式重新设置到元素上
ele.style.left = currentStyle + 'px';
}
},20);
}
3.多属性运动:
var box = document.querySelector(".box");
// 点击div让div向右移动到200px
box.onclick=function(){
sport(box,{"left":200,"top":300})
}
/*
* @ele 要运动的元素对象
* @attr 要运动css属性
* @target 运动的目标位置
*/
function sport(ele,obj){
for(let attr in obj){ // 为了不让后面的定时器覆盖前面的,将var改为let
let target = obj[attr]; // 为了多个属性不产生错误,将var改为let
// 获取当前样式
var currentStyle = window.getComputedStyle(ele)[attr];
// 获取到的是字符串,转为数字
currentStyle = parseInt(currentStyle);
// 设置定时器,让当前样式每隔20毫秒增加5px
let timer = setInterval(function(){ // 为了能将所有定时器都结束掉,将var改为let
currentStyle += 5;
// 判断增加后的样式是否到达指定距离
if(currentStyle >= target){
// 清除定时器
clearInterval(timer);
}else{
// 将增加后的样式重新设置到元素上
ele.style[attr] = currentStyle + 'px';
}
},20);
}
}
这种多个属性运动是不均匀的
4.均匀的多属性运动
var box = document.querySelector(".box");
// 点击div让div向右移动到200px
box.onclick=function(){
sport(box,{"left":200,"top":300})
}
/*
* @ele 要运动的元素对象
* @attr 要运动css属性
* @target 运动的目标位置
*/
function sport(ele,obj){
for(let attr in obj){ // 为了不让后面的定时器覆盖前面的,将var改为let
let target = obj[attr]; // 为了多个属性不产生错误,将var改为let
// 获取当前样式
let currentStyle = window.getComputedStyle(ele)[attr]; // 为了能让多属性均匀,将var改为let
// 获取到的是字符串,转为数字
currentStyle = parseInt(currentStyle);
// 设置定时器,让当前样式每隔20毫秒增加5px
let timer = setInterval(function(){ // 为了能将所有定时器都结束掉,将var改为let
// 计算比例
var percent = (target - currentStyle)/10;
// 为了能让定时器停止,需要处理比例
if(percent>0){
percent = Math.ceil(percent); // 向右运动
}else{
percent = Math.floor(percent); // 向左运动
}
// 当前样式不能都加5,否则不均与,所以加上比例
currentStyle += percent;
// 判断增加后的样式是否到达指定距离
if(currentStyle == target){ // 为了能向左运动,将>=改为==
// 清除定时器
clearInterval(timer);
}else{
// 将增加后的样式重新设置到元素上
ele.style[attr] = currentStyle + 'px';
}
},20);
}
}
5.处理运动结束:
var box = document.querySelector(".box");
box.onclick=function(){
sport(box,{"left":300,"opacity":0.5},function(){ // 向右移动300px,透明度变为0.5
sport(box,{"top":300,"opacity":0.8},function(){ // 向下运动300px,透明度变为0.8
sport(box,{"left":0,"opacity":0.2},function(){ // 向左运动300px,透明度变为0.2
sport(box,{"top":0,"opacity":0.9},function(){ // 最后向上运动300px,透明度变为0.9
alert('运动结束'); // 弹出'运动结束'
})
})
})
})
}
/*
* @ele 要运动的元素
* @obj 发生的改变组成的对象
* @attr 要运动css属性
* @target 运动的目标位置
* @endFN 运动结束后,要执行的函数
*/
function sport(ele,obj,endFN){
let timerObj = {}; // 将所有定时器都放到这个对象中
for(let attr in obj){ // 为了不让后面的定时器覆盖前面的,将var改为let
let target = obj[attr]; // 为了多个属性不产生错误,将var改为let
// 获取当前样式
let currentStyle = window.getComputedStyle(ele)[attr]; // 为了能让多属性均匀,将var改为let
// 当attr是透明度的时候,当前样式应该转为浮点数,并*100,因为传进来的目标是*100的
if(attr == 'opacity'){
currentStyle = parseFloat(currentStyle)*100;
// 传进来的目标缩小了100倍,所以这里再扩大100倍
target = target * 100;
}else{
// 获取到的是字符串,转为数字
currentStyle = parseInt(currentStyle);
}
// 设置定时器,让当前样式每隔20毫秒增加5px
// 通过每个css属性来识别这个定时器
timerObj[attr] = setInterval(function(){ // 为了能将所有定时器都结束掉,将var改为let
// 计算比例
let percent = (target - currentStyle)/10;
// 为了能让定时器停止,需要处理比例
if(percent>0){
percent = Math.ceil(percent); // 向右运动
}else{
percent = Math.floor(percent); // 向左运动
}
// 当前样式不能都加5,否则不均与,所以加上比例
currentStyle += percent;
// 判断增加后的样式是否到达指定距离
if(currentStyle == target){
// 清除定时器
clearInterval(timerObj[attr]);
// 每次结束一个定时器将这个定时器从定时器对象中删掉
delete timerObj[attr];
// 每次删掉定时器后,遍历定时器对象,计算定时器对象中定时器的个数
let k=0;
for(let i in timerObj){
k++;
}
// 如果个数是0,表示所有定时器都删掉了,也就意味着所有属性的运动都结束了
if(k==0){
// 当运动结束后想要做的事情,可以调用一个函数
endFN(); // 这个函数需要当做参数传进来
}
}else{
// 样式属性是透明度的时候,最后的值应该/100,并且不需要 px单位
if(attr == 'opacity'){
ele.style[attr] = currentStyle/100;
}else{
// 将增加后的样式重新设置到元素上
ele.style[attr] = currentStyle + 'px';
}
}
},20);
}
}