需求:点击div盒子让其向右移动100px
HTML和css部分
<style>
* {
padding: 0;
margin: 0;
}
.box {
width: 100px;
height: 100px;
background-color: pink;
position: absolute;
top: 0;
left: 0;
}
.box2 {
width: 100px;
height: 100px;
background-color: green;
position: absolute;
top: 200px;
left: 0;
}
</style>
<div class="box"></div>
<div class="box2"></div>
JS部分(基础版)
<script>
//封装一个运动函数
function move(ele,type,target){
* ele:表示移动哪个元素
* type:修改哪个属性
* target:移动的目标距离
let count = 0
const timer = setInterval(function(){
count += 5
ele.style[type] = count + 'px'
if(count == target){
clearInterval(timer)
}
},50)
}
const box = document.querySelector('.box')
const box2 = document.querySelector('.box2')
box.onclick = function () {
move(this, 'left', 200)
}
box2.onclick = function () {
move(this, 'left', 100)
}
</script>
那么通过上面代码的运行呢,我们可以发现存在一个问题,就是基础版的运动函数每一次点击div都会从0的位置开始移动
其原因呢就是因为运动函数的初始值,是从0开始的
解决方法:获取到元素的本身的值,然后在它本身的基础上移动
JS部分(基础版2)
<script>
// 封装一个运动函数
function move(ele, type, target) {
// 获取元素本身的值, 依次作为运动点
let count = parseInt(window.getComputedStyle(ele)[type])
const timer = setInterval(function () {
count += 5
ele.style[type] = count + 'px'
if (count == target) {
clearInterval(timer)
}
}, 50)
}
const box = document.querySelector('.box')
const box2 = document.querySelector('.box2')
box.onclick = function () {
move(this, 'left', 200)
}
box2.onclick = function () {
move(this, 'top', 400)
}
</script>
问题: 从 200 移动到 501 时, 不会停止
原因: 移动距离, 不是 每次移动的整倍数,现在从 200开始移动, 移动到501 移动距离 301,301 不是每次运动的整倍数
解决:
- 每次移动距离修改为 1
弊端, 运动速度固定了, 如果运动的路程不同, 就会导致时间不同 - 每次移动总路程的 1/10 (匀速)
现在从 200开始移动, 移动到501 移动距离 301
每次都移动 30.1
现在从 300开始移动, 移动501 移动距离 201
每次都移动 20.1 - 每次移动剩余路程的 1/10 (降速)
3.1 现在 从 0 开始移动, 移动到 100 移动距离 100
现在移动 100 / 10 === 10
3.2 现在 从 10 开始移动, 移动到 100 移动距离 90
现在移动 90 / 10 === 9
JS部分(进阶版1)
<script>
// 0. 封装一个运动函数
function move(ele, type, target) {
const timer = setInterval(function () {
// 1. 获取当前的位置
let count = parseInt(window.getComputedStyle(ele)[type])
// 2. 计算要移动的距离 (目标 - 当前的值) / 10
let des = (target - count) / 10
// 3. 判断是否需要继续移动
if (target === count) {
// 3.1 此时说明移动到了, 可以结束定时器
clearInterval(timer)
} else {
// 3.2 此时说明还没有移动到, 需要继续移动
ele.style[type] = count + des + 'px'
}
}, 20)
}
const box = document.querySelector('.box')
const box2 = document.querySelector('.box2')
box.onclick = function () {
move(this, 'left', 501)
// move(this, 'top', 200)
}
box2.onclick = function () {
move(this, 'left', 100)
}
</script>
问题: 没有移动到指定的距离
原因: 当前在的位置 91px 需要移动到 100px, 下一次移动距离 (100 - 91) / 10 === 0.9
当前移动的距离 应该是 91 + 0.9 + ‘px’ === 91.9px
但是浏览器可识别的最小移动距离 为 1px, 所以赋值移动到 91.9px 时, 实际位置 还是91px
解决: 将移动的距离 向上取整
新问题:
当前在的位置 9px 需要移动 0px, 下一次移动距离 (0 - 9) / 10 === -0.9
然后我们将移动值, 向上取整 -0.9 => 0
解决: 当移动的值 大于0的时候, 向上取整, 否则 向下取整
JS部分(进阶版2)
<script>
// 0. 封装一个运动函数
function move(ele, type, target) {
const timer = setInterval(function () {
// 1. 获取当前的位置
let count = parseInt(window.getComputedStyle(ele)[type])
// 2. 计算要移动的距离 (目标 - 当前的值) / 10
let des = (target - count) / 10
// 大于0 向上取整, 小于0 向下取整
des = des > 0 ? Math.ceil(des) : Math.floor(des)
// 3. 判断是否需要继续移动
if (target === count) {
// 3.1 此时说明移动到了, 可以结束定时器
clearInterval(timer)
} else {
// 3.2 此时说明还没有移动到, 需要继续移动
ele.style[type] = count + des + 'px'
}
}, 20)
}
const box = document.querySelector('.box')
const box2 = document.querySelector('.box2')
box.onclick = function () {
move(this, 'left', 0)
}
box2.onclick = function () {
move(this, 'left', 100)
}
</script>