- 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>Documenttitle>
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: #f00;
- position: absolute;
- left: 0;
- top: 50px;
- }
- style>
- <script>
-
- window.onload=function(){
- var begin=document.getElementById("begin");
- //上面获取begin应该和下面的方式一样,修改后可以显示,使用queryselectall不行
- var stop=document.getElementById("stop");
- var box=document.getElementById("box");
- var timer;
-
- //给开始按钮添加点击时间
- begin.onclick=function(){
- // 样式的结果带单位所以使用parseInt
- var l= parseInt(getComputedStyle(box).left);
- var t=parseInt(getComputedStyle(box).top);
- var w=parseInt(getComputedStyle(box).width);
- var h=parseInt(getComputedStyle(box).height);
-
- // 30ms是电影换帧的参数,看电影最流畅。浏览器刷新频率或者电脑硬件都会影响反应时间。这里设置为16
- timer=setInterval(function(){
- l++;
- t++;
- w++;
- h++;
- box.style.left=l+'px';
- box.style.top=t+'px';
- box.style.width=w+'px';
- box.style.height=h+'px';
- },16);
- // console.log(1);
- stop.onclick=function(){
- clearInterval(timer);
- };
- }
- };
- script>
- head>
- <body>
- <input type="button" id="begin" value="开始">
- <input type="button" id="stop" value="停止">
- <div id="box">div>
-
- body>
- html>
// 1.点击的时候需要getComputedStyle去获取到元素的属性值
// 2.点击开始按钮后开启一个重复执行定时器
// 3.在定时器里不断的修改元素的属性
QueryselectAll是静态获取,就是选出的元素不会随着文档的改变而变化
getElementById是动态获取,选的元素可以根据文档变化而变化

机械敲代码引发的低级 问题

运动的原理
在定时器里不断地去修改元素的属性,修改完成之后再把结果重新赋给元素
问题
1.如果每次的步长和目标值不成倍数,就到不了目标值
解决:把条件判断改成大于等于就可以
2.如果用户连续点击开始按钮,速度会越来越快
原因:用户不断点击开始按钮,会重复开启多个定时器造成速度累加
解决:再点击的时候先把上一个定时器清除。
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: #f00;
- position: absolute;
- left: 0;
- top: 50px;
- }
- style>
- <script>
- window.onload=function(){
- var begin=document.getElementById("begin");
- var box=document.getElementById("box");
- var t;
-
- begin.onclick=function(){
- clearInterval(t); //2.清除一个不存在的定时器是不会有问题的,第二次点击就会清除第一次的定时器
- // 开启定时器给t赋值
- t=setInterval(function(){
- var l=parseInt(getComputedStyle(box).left);
-
- // l++,改成下面的代码会让方块运动加快,一次运动7px
- l+=7;
- // box走到300停下来
- console.log(l);
- if(l>=300){ //问题1
- clearInterval(t);
- // l=300;
- }
- box.style.left=l+"px";
- },16);
- };
- }
- script>
3.如果有多个元素需要同时运动,那么前面的运动会没有效果
原因:因为每次运动开始都会清除上一个定时器,后面运动的时候清楚了前面的定时器,所以后面东前面不动了。
解决:使用自定义属性,只清除自己的定时器,不清楚别的定时器
- <style>
- #box1,#box2{
- width: 100px;
- height: 100px;
- background: red;
- position: absolute;
- left: 0;
- top: 50px;
- }
- #box2{
- top: 200px;
- }
- style>
- <script>
- window.onload=function(){
- var btn=document.getElementById("btn");
- var box1=document.getElementById("box1");
- var box2=document.getElementById("box2");
- var t;//所有元素共用一个定时器
-
- function move(obj,attr,target){
- // 清除定时器累加
- // clearInterval(t);
- clearInterval(obj.t);//一上来只清除自己的定时器不会清除别人的定时器
- obj.t=setInterval(function(){
- var value=parseInt(getComputedStyle(obj)[attr]);//获取到属性的值
-
- value+=7;//让属性值不断+7
- //如果属性值已经超过目标了,要定时清理定时器,同时为了避免越界,要把它拉回
- if(value>=target){
- clearInterval(t);
- value=target;
- }
- //修改元素的属性值
- obj.style[attr]=value+'px';
- },16);
- }
- btn.onclick=function(){
- move(box1,'left',300);
- move(box2,'left',250);
- }
- }
-
- script>
-
- <body>
- <input type="button" id="btn" value="开始">
- <div id="box1">div>
- <div id="box2">div>
- body>
tip:两个物体运动不需要把代码写两份,封装函数即可
运动框架move.js
通过vscode终端命令引入move.js

限定时间的运动,根据时间去控制速度,已知时间和距离,计算速度
匀速运动
特点:在任何一个点的速度都是一样的
某个点的位置=速度x时间
速度=总距离/总时间
时间=现在的时间-开始的时间
某个点的位置=总的距离/总的时间*(现在的时间-开始的时间)
t已过的时间
b开始的时间
c总距离
d总时间
b是元素开始的位置,起点不一定在0,0,参数里的目标值是要运动到的那个点,而不是要走的距离。所以元素如果不在0,0开始运动的话,需要把起始点的距离加上。
var value=c/d*t+b
- 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>Documenttitle>
- <script>
- window.onload=function(){
- var btn=document.getElementById("btn");
- var box=document.getElementById("box");
-
- btn.onclick=function(){
- var c=300;
- var d=2000;
- var b=parseInt(getComputedStyle(box).left);
-
-
- //一开始运动的时候要记录开始的时间
- var startTime=new Date().getTime();
-
- //开启定时器
- var timer=setInterval(function(){
- var t=new Date().getTime-startTime;
-
- var value=c/d*t+b;
-
- box.style.left=value+'px';
- },16);
- }
- };
- script>
- head>
- <body>
- <input type="button" id="btn" value="开始">
- <div id="box">div>
- body>
- html>
下面的代码引用了Tween.js运动框架的js脚本,复制运行请自行添加。
- 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>Documenttitle>
- <style>
- #box{
- width: 100px;
- height: 100px;
- background: red;
- position: absolute;
- left: 0;
- top: 50px;
- }
- style>
- <script>
- /*
- obj运动的对象
- attr 要运动的对象
- target 要运动到的目标
- duration要运动的时间
- fx运动的形式
- callBack运动完成之后调用的函数
- */
- function move( obj,attr,target,duration,fx,callBack){
- var d=duration;
- //起始位置
- var b=parseFloat(getComputedStyle(obj)[attr]) //attr是变量不是真正的属性所以使用中括号
- var c=target-b;
- var startTime=new Date().getTime();
-
- clearInterval(obj.timer);
- obj.timer=setInterval(function(){
- var t=new Date.getTime()-startTime;
- // 运动停止
- if(t>=d){
- t=d;
- clearInterval(obj.timer);
- }
- //var value=c/d*t+b;
- var value=Tween[fx](t,b,c,d);
- obj.style[attr]=value+'px';
- // 1
- if(t==d){
- if(callBack){
- // 存在就调用
- callBack();
- }
- }
- // 2
- if(t==d){
- // 左真返回右,左假返回左,就什么都不做
- callBack && callBack();
- }
-
- },16);
-
-
- }
- window.onload=function(){
- var btn=document.getElementById("btn");
- var box=document.getElementById("box");
-
- btn.onclick=function(){
- move(box,'left',400,1000,'linear',function(){
- alert('运动完成了')
- });
- }
- }
-
- script>
- head>
- <body>
- <input type="button" id="btn" value="开始">
- <div id="box">div>
- body>
- html>
也可以在运动完成了的方法内调用move
- btn.onclick=function(){
- // move(box,'left',400,1000,'linear',function(){
- // alert('运动完成了')
- // });
-
- // 注意move函数的调用语法
- move(box,'left',400,1000,'bounceIn');
- }
move(obj,{left:10,top:20,opacity:0.8},duration,fx,callback)
只有callback不是必须的额
第二个参数里面用的键值对的形式,值没有单位,opacity的值是0-1