函数需求
初始值需要获取标签的原始属性的数据
获取相应标签的属性
最终位置可控制
作为一个参数,进行输入
多种属性一起运动
使用 对象 来 存储 运动属性和最终值
每次累加的数值,不一定就是正数,甚至每次累加的数值,都有可能不是固定的数值
每次改变的数值,就设定成,一个改变的数值:( 最终值 - 初始值 ) / 完成次数
取整: 步长大于 0 向上取整,步长小于 0 向下取整
判断每一个属性是否到达最终位置,并清除相应定时器
每次生成一个定时器,就向对象中存储一个定时
对象的属性是运动属性的名称 也就是当前运动的是left 对象的属性就是left
对象的属性值是定时器的序号
判断运动停止了
每次清除定时器便删除相应的对象属性
判断创建的对象是否为空,为空则运动停止
htmlcssjs
<button>开始</button>
<div></div>
* {
margin: 0;
padding: 0;
}
div {
width: 400px;
height: 400px;
background: pink;
position: fixed;
top: 0px;
left: 500px;
}
// 获取标签css样式的兼容语法函数
// 参数1: 需要获取样式的标签对象
// 参数2: 需要获取样式的属性名称
function myGetStyle(element, style) {
// 如果 浏览器 支持 window.getComputedStyle 执行结果有内容,自动转化为 true
// 如果 浏览器 不支持 window.getComputedStyle 执行结果,为undefined,自动转化为 false
if (window.getComputedStyle) {
// window.getComputedStyle 转化为 true 的情况
// 也就是 浏览器 支持 window.getComputedStyle 可以使用
return window.getComputedStyle(element)[style];
} else {
// window.getComputedStyle 转化为 false 的情况
// 浏览器不支持 window.getComputedStyle 方法 不能使用
return element.currentStyle[style];
}
}
var oDiv = document.querySelector('div');
var oBtn = document.querySelector('button');
// 点击button按钮,执行 运动函数
oBtn.addEventListener('click', () => {
move(oDiv, {left:3,top:50});
})
function move(element, typeObj) {
// 定义一个对象,存储定时器
var obj = {};
// type就是运动的属性,也就是 left top width...
for(let type in typeObj){
// setInterval() 执行结果,是 定时器的编号
// 对象[type] 就是 将 type 运动属性left等,作为对象的属性
// 将 setInterval() 的执行结果,也就是 1,2,3... 等编号,作为对象的属性值
obj[type] = setInterval(() => {
// 1, 获取初始值
let startVal = parseInt(myGetStyle(element, type));
// 2, 累加数值 / 步长 应该是 ( 最终值 - 初始值 ) / 设定的次数
// 步长值 ,最终几次执行,有可能,是小数,累加的结果是不足1的
// css样式中,对于不足1的小数像素,执行,有可能是向下取整,有可能是向上取整
// 需要要先对,speed,步长值取整 0.5 向上取整是 1
// -0.5 向下取整是 -1
// speed 大于 0 , 向上取整, 否则 就向下取整
let speed = ( typeObj[type] - startVal ) / 5;
// 对 speed 取整:
// speed 如果 大于 0 ,就将 speed 向上取整,赋值给 speed 本身
// speed 如果 小于 0 ,就将 speed 向下取整,赋值给 speed 本身
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
// 初始值 累加 步长 (步长,有可能是正数,也有可能是负数)
startVal += speed;
// 3, 将累加之后的数值,赋值给标签css样式的属性值
element.style[type] = startVal + 'px';
// 4, 判断,如果到了最终目标位置,停止定时器
// startVal 是 当前的属性值
// typeObj[type] 是 最终属性值 top:500 left:1000
if(startVal === typeObj[type]){
// 清除定时器
// 应该是 clearInterval(定时器编号)
// 当前编号存储在对象的属性中
// 要想获取 应该是 obj[运动属性]
clearInterval(obj[type]);
// 定出掉的定时器,就从对象中删除
delete(obj[type]);
// 如果对象是一个空对象,证明所有的定时器都清除了
// 证明运动真的停止了
// 使用: Object.keys(对象) JavaScript提供的方法
// 获取对象中,所有的键名,组成一个数组
// 当对象是一个空对象,数组就是一个空数组,length就是0
const objKeyArr = Object.keys(obj);
if(objKeyArr.length === 0){
// 如果数组的长度是 0 ,证明数组是一个空数组,对象是一个空对象
console.log('所有运动真的停止了')
}
}
}, 30)
}
}
兼容px,rem,em单位
作为一个参数,进行输入
兼容透明度
如果运动属性是透明度,获取初始值,放大一个固定倍数,一般是 100倍
最终数值,步长,等都要按照倍数执行
赋值时,要去掉px单位
htmlcssjs
<button>开始</button>
<div></div>
* {
margin: 0;
padding: 0;
}
div {
width: 400px;
height: 400px;
background: pink;
position: fixed;
top: 0px;
left: 500px;
}
// 获取标签css样式的兼容语法函数
// 参数1: 需要获取样式的标签对象
// 参数2: 需要获取样式的属性名称
function myGetStyle(element, style) {
// 如果 浏览器 支持 window.getComputedStyle 执行结果有内容,自动转化为 true
// 如果 浏览器 不支持 window.getComputedStyle 执行结果,为undefined,自动转化为 false
if (window.getComputedStyle) {
// window.getComputedStyle 转化为 true 的情况
// 也就是 浏览器 支持 window.getComputedStyle 可以使用
return window.getComputedStyle(element)[style];
} else {
// window.getComputedStyle 转化为 false 的情况
// 浏览器不支持 window.getComputedStyle 方法 不能使用
return element.currentStyle[style];
}
}
var oDiv = document.querySelector('div');
var oBtn = document.querySelector('button');
// 点击button按钮,执行 运动函数
oBtn.addEventListener( 'click' , function(){
move( oDiv , {left: 600 , top:400 , width:600 , height:400 , fontSize : 300 , opacity: .4} ,'', function(){
oDiv.style.background = 'blue';
oDiv.style.color = '#fff';
console.log('所有运动结束了');
},1,1000);
})
// 运动函数的封装
// 参数1 : 运动的标签对象
// 参数2 : 运动标签对象的属性和最终值 ( 必须是 对象类型 )
// 参数3 : 运动标签对象的单位 'px' 'rem' 'em'
// 参数4 : 运动停止时,执行的回调函数, 可以是匿名函数,或者定义好的函数名称
// 参数5 : 运动停止时,是否还原初始值
// 参数6 : 运动停止时,是否还原初始值需要的时间
function move(element , typeObj , style, fun, state, time){
// 1.创建一个对象,存储定时器
const IntervalObj = {};
// 2.创建一个对象,存储数据初始状态
const obj={};
// 3.使用for..in 循环遍历参数
// 自定义变量,必须使用let声明
for( let type in typeObj ) {
obj[ type ] = parseInt(myGetStyle(element , type));
// 每次循环都创建一个定时器,存储在定时器对象中
IntervalObj[type] = setInterval( ()=>{
// 1, 获取初始值 , 如果是 透明度 , 初始值 和 最终值 都要乘以 100
var startVal = type === 'opacity' ? myGetStyle(element , type)*100 : parseInt( myGetStyle(element , type) );
// 获取最终数值,如果是透明度就乘以100
var endVal = type === 'opacity' ? typeObj[type]*100 : typeObj[type];
// 2, 计算步长: (最终值 - 初始值 ) / 设定的次数
// 设定次数,不是定时器执行的次数
var speed = ( endVal - startVal ) / 5;
// 3, 对步长取整,大于0,向上取整,小于0,向下取整
speed = speed > 0 ? Math.ceil( speed ) : Math.floor( speed );
// 4, 初始值,累加步长
startVal += speed;
// 5, 将新的数值,设定给 标签
// 是 透明度 除以100 设定, 不是透明度拼接px设定
if(style == null || style == ''){
element.style[type] = type === 'opacity' ? startVal/100 : startVal + 'px';
}else{
element.style[type] = type === 'opacity' ? startVal/100 : startVal + style;
}
// 6, 判断,如果 初始值累加至最终值,清除 当前运动属性,对应的定时器,停止运动
if( startVal === endVal ){
// 清除 当前运动属性 对应的 定时器
clearInterval( IntervalObj[type] );
// 清除 对象中 当前属性 对应的单元
delete( IntervalObj[type] );
// 使用 Object.keys() 获取 对象中的所有属性,组成数组
const typeArr = Object.keys( IntervalObj );
// 如果数组的长度是0,对象,就是空对象,所有定时器都清除了,所有运动属性都停止了
if(typeArr.length === 0){
// 调用运动停止时,执行的函数,参数3
fun();
if(state === 1){
setTimeout(function(){
for(let type in obj){
if(style == null || style == ''){
element.style[type] = type === 'opacity' ? obj[type] : obj[type]+'px'
}else{
element.style[type] = type === 'opacity' ? obj[type] : obj[type]+'px'
}
}
},time)
}
}
}
} , 30 );
}
}
动画结束是否恢复原始状态
作为一个参数,进行输入(0是不恢复状态,1是恢复状态)
将dome的属性存入一个对象当中,在结束后恢复对象属性
并再添加一个恢复原始状态的定时数
动画结束进行其他函数
作为一个参数,写入一个要执行的函数
Comments | NOTHING