此时有一个div元素,样式如代码所示:
div {
height: 100px;
width: 100px;
background: blue;
position: absolute;
top: 0;
left: 0;
}
此时,我们想点击元素时,让这个元素向左运动起来,并且运动到一个target值时就自动停止。是不是很容易就想到了定时器,此处仅通过JS代码实现,不使用c3中的animation动画特效。所以使用定时器让它间隔一段时间一直进行循坏的让div的left值增加,此处可以设置一个累加变量来实现。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
height: 100px;
width: 100px;
background: blue;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div>Be best!</div>
<script>
let div = document.querySelector("div");
let divCss = window.getComputedStyle(div);
let target = 600;
// console.log(divCss);
div.onclick = function () {
let timer = null;
let count = parseInt(divCss.left);
timer = setInterval(() => {
count += 5;
if (count >= target) {
div.style.left = target + "px";
clearInterval(timer);
} else {
div.style.left = count + "px";
}
}, 20);
};
</script>
</body>
</html>
这里需要注意两个点:1.使用getComputedStyle()得到的样式值只读不能修改
2.取出的样式值是带有单位的,要使用parseInt()来取到它的整数值
接下来,加大难度,如果我们想要得到一个可以做到往任意方向移动的运动函数呢?所以,此时就需要写一个带有形参的函数了,把所需要的值当成实参给传递进去。此处只能最多是两个方向,在二维空间中不可能做到三个方向同时运动。
代码实现如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
height: 100px;
width: 100px;
background: blue;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div>Be best!</div>
<script>
let div = document.querySelector("div");
let divCss = window.getComputedStyle(div);
//此处设定的是div在该方向上移动并到该值时停止
move(div, { left: 600, top: 300 });
function move(ele, styleObj) {
ele.onclick = function () {
let timer = null;
for (let attr in styleObj) {
let count = parseInt(getComputedStyle(ele)[attr]);
timer = setInterval(() => {
count += 5;
if (count >= styleObj[attr]) {
ele.style[attr] = styleObj[attr] + "px";
clearInterval(timer);
} else {
ele.style[attr] = count + "px";
}
}, 20);
}
};
}
</script>
</body>
</html>
当写了多方向会发现,如果两侧运动走过的距离不同时,两侧并不是同时到达目的地并且停止,如果要让两个方向同步进行,则就需要两个方向在行走的过程中一直保证在对角线上行驶。这里提供两种方式:一种方式是可以实现两个方向的同步进行,并且是匀速的,但是只限制了在两个方向上有一个方向走过的距离是另一方向的整数倍时才可以实现,因为这里的思路是取到他们两个之间的倍数值,让走过路程距离长的那一方向上走的路程是短的那层走过路程的倍数,就可以实现同步,eg:如果传入的参数对象是{left:600,top:300},则这里left/top=2,则这里就是当top方向走1px时,left方向走2px,此时就会实现同时到达并停止的想法,但是因为浏览器中的像素只能走整数倍,所以当这个倍数不是整数别的时候就会出问题,只要一取整就会存在误差,所以我们就需要在他每一次执行完的下一步都让他在计算一下他重新的比例,然后走的距离又是不一样的,按理说是可以实现的,不过因为暂时没有时间去具体写这个代码,后续写出会继续更新此方法,这里附上只是整数倍时实现的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
height: 100px;
width: 100px;
background: blue;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div>Be best!</div>
<script>
var div = document.querySelector("div");
var divCss = window.getComputedStyle(div);
var target = 600;
function move(ele, styleObj) {
var x,
num,
i = 0;
var arr = new Array();
for (var j = 0; j <= 1; j++) {
arr[j] = new Array();
}
for (let item in styleObj) {
// console.log(styleObj[item]);
arr[i][0] = item;
arr[i][1] = styleObj[item];
i++;
}
// console.log(arr);
if (arr[0][1] > arr[1][1]) {
var maxStyle = arr[0][0];
var minStyle = arr[1][0];
}
// console.log(maxStyle);
ele.onclick = function () {
for (let attr in styleObj) {
let timer = null;
var count = parseInt(getComputedStyle(ele)[attr]);
var num = parseInt(getComputedStyle(ele)[attr]);
timer = setInterval(() => {
if (attr == maxStyle) {
var percent = parseInt(styleObj[maxStyle] / styleObj[minStyle]);
// console.log(percent);
count += percent;
if (count > styleObj[attr]) {
this.style[attr] = styleObj[attr] + "px";
clearInterval(timer);
} else {
this.style[attr] = count + "px";
}
} else {
num++;
if (num > styleObj[attr]) {
this.style[attr] = styleObj[attr] + "px";
clearInterval(timer);
} else {
this.style[attr] = num + "px";
}
// console.log(count);
}
}, 20);
}
};
}
move(div, { left: 600, top: 300 });
</script>
</body>
</html>
同时提供另一种逐渐减速但依然在对角线上运动的思路方法,也就是把每次剩下的路程看做10份,每次只走十分之一,这里就是以他们各自走的路程作为参照物,所用时间大致相同,所以也可以实现按对角线运动,但是每次的路程的1/10都在缩短,所以速度会越来越短,因为也会存在取整,所以最后有一点点不同步。
代码实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
height: 100px;
width: 100px;
background: blue;
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div>Be best!</div>
<script>
let div = document.querySelector("div");
let divCss = window.getComputedStyle(div);
function move(ele, styleObj) {
ele.onclick = function () {
for (let attr in styleObj) {
let count = parseInt(getComputedStyle(ele)[attr]);
let timer = null;
timer = setInterval(() => {
let length = (styleObj[attr] - count) / 10;
if (length > 0) {
length = Math.ceil(length);
} else {
length = Math.floor(length);
}
count += length;
if (count == styleObj[attr]) {
this.style[attr] = styleObj[attr] + "px";
clearInterval(timer);
} else {
this.style[attr] = count + "px";
}
}, 50);
}
};
}
move(div, { left: 600, top: 300 });
</script>
</body>
</html>
当然,在这运动函数中还可以继续增加其他的属性值和变换,有兴趣的小可爱们可以试试,后期如果有时间我也会更新同时事项其他样式的代码。