运动函数

运动函数第一版
// ele 要运动的元素
// type 要运动的样式名
// 要运动的目标位置  target
function move(ele,type,target) {
	let distance = 0;
	const timer = setInterval(()=>{
		distance += 5;
		ele.style[type] = distance  + 'px';
		if(distance >= target){
			clearInterval(timer);
		}
	},20)
}

问题:如果我的元素起始位置不是0?则会跳到0从0开始进行移动
=》因为在封装的时候,distance开始时始终是0
=》不管元素的开始位置是什么,运动的开始位置一定是0

解决:
=》再加一个参数
=》不好,尽量不添加参数
=》直接拿到元素的开始位置
=》当元素需要运动的是left属性,在运动开始之前,拿到left属性

运动函数第二版

问题:如何获取元素的初始位置?
=》 获取元素的非行内样式left
=> 标准浏览器:window.getComputedStyle(元素).样式名
注意:拿到的值是带有px的,不要忘记使用parseInt()

function move(ele,type,target) {
	// let distance = 0;
	let distance = parseInt(window.getComputedStyle(ele)[type]);
	const timer = setInterval(()=>{
		distance += 5;
		ele.style[type] = distance  + 'px';
		if(distance >= target){
			clearInterval(timer);
		}
	},20)
}

问题: 元素运动的初始值和目标值不一定是整数

运动函数第三版

解决:把每次运动的距离改为1,把定时器的时间调整的快一点
问题:如果调整为每次运动距离为1,那么当多个属性一起运动的时候,有的先完成,有的后完成
解决:把匀速运动改成非匀速运动
=》通过速度的不一致,得到最终运动的时间一致
实现:
=》只要不让你每次都运动1px,不管你运动总距离是多少,都固定每次运动剩余距离的10分之1
=》每次的定时器拿到当前的left位置是多少
=》目标位置-当前位置,求出来的是剩余距离
=》剩余距离/10,求出,本次应该运动的距离
=》判断当前位置是否到达目标位置
如果到达目标位置,停止定时器
如果没到达目标位置,赋值:当前位置+本次运动距离

function move(ele,type,target) {
	const timer = setInterval(()=>{
		// 1.拿到当前位置
		let current= parseInt(window.getComputedStyle(ele)[type]);	
		// 2.计算本次运动距离
		let distance = (target - current) /10;
		// 3.判断
		if(current === target){
			clearInterval(timer)
		}else{
			ele.style[type] = current + distance + 'px';
		}
	},20)
}

问题:没有办法到达目标位置?
=》随着运动,一定会到达一个临界点,还差不到10px到目标位置了
=》当你剩余距离还剩9px的时候
=》计算出的本次运动距离0.9px
=> 因为浏览器能描述的最小像素是1px
=> 0.9px就不会运动了,就停在原位
=》导致下次还是剩余9px,计算的运动距离还是0.9,还是不会运动

解决:取整
=》向上取整

运动函数第四版
function move(ele,type,target) {
	const timer = setInterval(()=>{
		// 1.拿到当前位置
		let current= parseInt(window.getComputedStyle(ele)[type]);	
		// 2.计算本次运动距离
		let distance = (target - current) /10;
		distance = Math.ceil(distance);
		// 3.判断
		if(current === target){
			clearInterval(timer)
		}else{
			ele.style[type] = current + distance + 'px';
		}
	},20)
}

问题:向负方向运动
=》因为操作向上取整,当你向负方向运动的时候,一定能在过程中计算出-0.9的数字
=》-0.9向上取整,得到0,导致本次运动距离是0,下次拿到的运动距离依旧是-0.9
解决:向下取整
正负兼容

function move(ele,type,target) {
	const timer = setInterval(()=>{
		// 1.拿到当前位置
		let current= parseInt(window.getComputedStyle(ele)[type]);	
		// 2.计算本次运动距离
		let distance = (target - current) /10;
		distance = distance > 0 ? Math.ceil(distance): Math.floor(distance);
		// 3.判断
		if(current === target){
			clearInterval(timer)
		}else{
			ele.style[type] = current + distance + 'px';
		}
	},20)
}

问题:想运动下opacity?
=>赋值的时候带有px单位
=>因为opacity是不需要带有单位的
=>赋值的时候,需要判断一下,如果是opacity不需要加单位
=>如果不是opacity才加单位单位

问题:没有运动的过程?
=> 因为拿到的值是1,目标位置是0
=>本次的运动距离一定是(0-1)/10 ,得到的是-0.1,取整以后,得到的是-1
=>赋值的时候,opacity = 1±1直接等于0
解决:获取值的时候,放大100倍,赋值的时候缩小100倍

问题:没办法向正方向运动?
注意:当你需要运动opacity的时候
=》最好在给值调用的时候,按照0-100的区间给值

function move(ele,type,target) {
	const timer = setInterval(()=>{
		// 1.拿到当前位置
		let current;
		if(type === 'opacity') {
			current= parseInt(window.getComputedStyle(ele)[type])*100;
		}else{
			current= parseInt(window.getComputedStyle(ele)[type]);	
		}
		// 2.计算本次运动距离
		let distance = (target - current) /10;
		distance = distance > 0 ? Math.ceil(distance): Math.floor(distance);
		// 3.判断
		if(current === target){
			clearInterval(timer)
		}else{
			// 判断你运动的是不是opacity样式
			if(type === 'opacity'){
				ele.style[type] = (current + distance)/100;
			}else {
				ele.style[type] = current + distance + 'px';
			}
		}
	},20)
}

问题:一个函数只能运动一个属性
=》因为刚才设计的函数就是单属性运动函数
方案1:添加参数个数 =》不好
方案2:以对象的形式传递需要运动的内容

function move(ele,target) {
	// ele要运动的元素,target是要运动的很随性,是一个对象数据类型
	// 拿到我需要运动的每一个样式和目标值,遍历对象
	for(let k in target){
		// k是要运动的样式名  target[k]是运动的目标值
		const timer = setInterval(()=>{
		// 1.拿到当前位置
		let current;
		if(k=== 'opacity') {
			current= parseInt(window.getComputedStyle(ele)[k])*100;
		}else{
			current= parseInt(window.getComputedStyle(ele)[k]);	
		}
		// 2.计算本次运动距离
		let distance = (target[k]- current) /10;
		distance = distance > 0 ? Math.ceil(distance): Math.floor(distance);
		// 3.判断
		if(current === target[k]){
			clearInterval(timer)
		}else{
			// 判断你运动的是不是opacity样式
			if(k === 'opacity'){
				ele.style[k] = (current + distance)/100;
			}else {
				ele.style[k] = current + distance + 'px';
			}
		}
	},20)
	}
}

问题:如何捕获到运动完全结束了?最后一个定时器关闭是什么时候
需要在运动结束的时候,在控制台打印一下结束了
=》开启多少个定时器,就会关闭多少个定时器,每关闭一次就会执行一次运动结束的打印
解决:准备一个计数器,每开启一个定时器,计数器++,每关闭一个定时器–

function move(ele,target) {
	// ele要运动的元素,target是要运动的很随性,是一个对象数据类型
	// 拿到我需要运动的每一个样式和目标值,遍历对象
	
	// 准备一个定时器
	let count = 0;
	
	for(let k in target){
		// k是要运动的样式名  target[k]是运动的目标值
		const timer = setInterval(()=>{
		// 1.拿到当前位置
		let current;
		// 每执行一个定时器,进行++
		count++;
		if(k=== 'opacity') {
			current= parseInt(window.getComputedStyle(ele)[k])*100;
		}else{
			current= parseInt(window.getComputedStyle(ele)[k]);	
		}
		// 2.计算本次运动距离
		let distance = (target[k]- current) /10;
		distance = distance > 0 ? Math.ceil(distance): Math.floor(distance);
		// 3.判断
		if(current === target[k]){
			clearInterval(timer)
			// 每关闭一个计时器
			count--;
			// 判断count === 0的时候,就是所有的定时器完全关闭了
			if(count === 0){
				console.log("运动完全结束了")
			}
		}else{
			// 判断你运动的是不是opacity样式
			if(k === 'opacity'){
				ele.style[k] = (current + distance)/100;
			}else {
				ele.style[k] = current + distance + 'px';
			}
		}
	},20)
	}
}

需求:div运动结束以后,在控制台打印运动结束

function move(ele,target,fn) {
	// ele要运动的元素,target是要运动的很随性,是一个对象数据类型
	// 拿到我需要运动的每一个样式和目标值,遍历对象
	
	// 准备一个定时器
	let count = 0;
	
	for(let k in target){
		// k是要运动的样式名  target[k]是运动的目标值
		const timer = setInterval(()=>{
		// 1.拿到当前位置
		let current;
		// 每执行一个定时器,进行++
		count++;
		if(k=== 'opacity') {
			current= parseInt(window.getComputedStyle(ele)[k])*100;
		}else{
			current= parseInt(window.getComputedStyle(ele)[k]);	
		}
		// 2.计算本次运动距离
		let distance = (target[k]- current) /10;
		distance = distance > 0 ? Math.ceil(distance): Math.floor(distance);
		// 3.判断
		if(current === target[k]){
			clearInterval(timer)
			// 每关闭一个计时器
			count--;
			// 判断count === 0的时候,就是所有的定时器完全关闭了
			if(count === 0){
				fn();
			}
		}else{
			// 判断你运动的是不是opacity样式
			if(k === 'opacity'){
				ele.style[k] = (current + distance)/100;
			}else {
				ele.style[k] = current + distance + 'px';
			}
		}
	},20)
	}
};

const box= document.querySelect("div");
div.onClick=function(){
		move(box,{
			left:600,
			top:300,
			width:400,
			height:200,
			opacity:35
		},()=>{console.log("运动结束了")})
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值