使用JavaScript 实现对象 匀速/变速运动的方法


Posted in Javascript onMay 08, 2013

实例1——控制一个对象的匀速移动和停止

HTML:

<input id="btn" type="button" value=" Move It ! "/>
    <div id="d1">
        <img id="i1" src="1.jpg" alt/>
    </div>

JS:实现向右运动
var timer=null;
    window.onload=function(){
        var odiv=document.getElementById('d1');
        var obtn=document.getElementById('btn');
        clearInterval(timer); //作用见要点①
        obtn.onclick=function(){
            timer=setInterval(function(){
                var speed=10;
                if(odiv.offsetLeft>=300){ //判断对象边距 到达指定位移则关闭定时器
                    clearInterval(timer);
                }else{
                    odiv.style.left=odiv.offsetLeft+speed+'px';
                }
            },30);
        }
    }

要点:
①if语句的条件不能用“==”运算符,如上述代码,当speed的值为基数如7时,不断增加的左边距不会出现300px值,而是到达294后直接跳到301,导致条件失效,无法停止。
②使用else语句是防止停止移动后,每点击一次按钮,div任会移动一个speed。
③在定时器之前,先关闭一下定时器,防止连续点击按钮时,同时打开多个定时器,使移动速度叠加后更快。

封装:

//object:要移动的对象id   itarget:水平位移位置
   var timer=null;
    function moveto(object,itarget){
        var obj=document.getElementById(object);
            clearInterval(timer);
            timer=setInterval(function(){
                var speed=0;
                if(obj.offsetLeft<itarget){  //通过对象距离父级的边距和水平位移量 判断左右位移方向
                    speed=10;
                }else{
                    speed=-10;
                }
                if(obj.offsetLeft==itarget){
                    clearInterval(timer);
                }else{
                    obj.style.left=obj.offsetLeft+speed+'px';
                };
            },30);
    }

实例2——修改上述封装的函数moveto(),使该对象变速停止

 JS:

var timer=null;
    function moveto(object,itarget){
        var obj=document.getElementById(object);
            clearInterval(timer);
            timer=setInterval(function(){
                var speed=0;
                if(obj.offsetLeft<itarget){//通过位移量除以10,使speed递减,实现减速停止。   乘以10则为加速。通过乘除的数字,控制快慢
                    speed=(itarget-obj.offsetLeft)/10; 
                }else{
                    speed=-(obj.offsetLeft-itarget)/10;
                }
                speed=speed>0?Math.ceil(speed):Math.floor(speed);//取整,解决最后不足1px的位移量被忽略的问题
                if(obj.offsetLeft==itarget){
                    clearInterval(timer);
                }else{
                    obj.style.left=obj.offsetLeft+speed+'px';
                };
                document.title=obj.offsetLeft;
            },30);
    }

要点:
①通过递减speed值,实现变速。
②移动到最后,当像素小于1px时,小于1px的几个值不会被添加(或减去)到对象left中,而是被忽略,所以最终位移量比设定的水平位移位置itarget要少几个像素。解决的办法是进行取整:正数向上取整ceil(),负数向下取整floor()。

 

 扩展:垂直位移的原理和水平位移的相同。

 补充1:
解决speed与itarget不能整除,导致对象不能精确到达itarget位置,而是在其左右抖动问题:

var timer=null;
    function moveto(object,itarget){
        var obj=document.getElementById(object);
            clearInterval(timer);
            timer=setInterval(function(){
                var speed=0;
                if(obj.offsetLeft<=itarget){
                    speed=7;
                }else{
                    speed=-7;
                }
//设置对象在离目标位置itarget的距离小于speed时,停止运动,同时设置对象的left直接移动到itarget的位置。
                if(Math.abs(itarget-obj.offsetLeft<=speed)){
                    clearInterval(timer);
                    obj.style.left=itarget+'px';
                }else{
                    obj.style.left=obj.offsetLeft+speed+'px';
                };
                document.title=obj.offsetLeft;
            },30);
    }

补充2:

offset的Bug:例如offsetWidth,它包含的不只是width,还包含padding和border。当给对象设置了填充或边框时,再将offsetWidth赋值给对象时,就会运动就会有差异。
解决:不用offset,而是通过创建一个兼容IE和FF的函数,获取元素的width属性值,来代替offsetWidth。该函数如下:getAttr()

function getAttr(obj,attrName){
        var obj=document.getElementById(obj);
        if(obj.currentStyle){
            return obj.currentStyle[attrName]; //兼容IE
        }else{
            return getComputedStyle(obj,false)[attrName]; //兼容FF
        }
    }
Javascript 相关文章推荐
JavaScript入门教程(8) Location地址对象
Jan 31 Javascript
基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
May 07 Javascript
使用text方法获取Html元素文本信息示例
Sep 01 Javascript
jQuery使用after()方法在元素后面添加多项内容的方法
Mar 26 Javascript
jQuery平滑旋转幻灯片特效代码分享
Sep 07 Javascript
JS上传组件FileUpload自定义模板的使用方法
May 10 Javascript
浅谈bootstrap使用中的一些问题以及解决过程
Oct 18 Javascript
bootstrap实现图片自动轮播
Dec 21 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
May 11 Javascript
微信小程序中的列表切换功能实例代码详解
Jun 09 Javascript
vue接通后端api以及部署到服务器操作
Aug 13 Javascript
小程序实现筛子抽奖
May 26 Javascript
JavaScript 创建运动框架的实现代码
May 08 #Javascript
jQuery输入城市查看地图使用介绍
May 08 #Javascript
深入Javascript函数、递归与闭包(执行环境、变量对象与作用域链)使用详解
May 08 #Javascript
基于jquery实现拆分姓名的方法(纯JS版)
May 08 #Javascript
jQuery cdn使用介绍
May 08 #Javascript
不用锚点也可以平滑滚动到页面的指定位置实现代码
May 08 #Javascript
jquery实现图片左右间隔滚动特效(可自动播放)
May 08 #Javascript
You might like
PHP之变量、常量学习笔记
2008/03/27 PHP
php处理文件的小例子(解压缩,删除目录)
2013/02/03 PHP
php实现过滤表单提交中html标签的方法
2014/10/17 PHP
php数组使用规则分析
2015/02/27 PHP
php和js实现根据子网掩码和ip计算子网功能示例
2019/11/09 PHP
编写兼容IE和FireFox的脚本
2009/05/18 Javascript
jQuery $.each的用法说明
2010/03/22 Javascript
js获取GridView中行数据的两种方法 分享
2013/07/13 Javascript
使用javascript创建快捷方式的简单实例
2013/08/09 Javascript
jQuery实现tag便签去重效果的方法
2015/01/20 Javascript
js判断登录与否并确定跳转页面的方法
2015/01/30 Javascript
Jquery效果大全之制作电脑健康体检得分特效附源码下载
2015/11/02 Javascript
jQuery CSS3相结合实现时钟插件
2016/01/08 Javascript
通用无限极下拉菜单的实现代码
2016/05/31 Javascript
浅谈时钟的生成(js手写简洁代码)
2016/08/20 Javascript
Ajax+FormData+javascript实现无刷新表单信息提交
2016/10/24 Javascript
javascript设置文本框光标的方法实例小结
2016/11/04 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
微信小程序图片宽100%显示并且不变形
2017/06/21 Javascript
在Vue.js中使用Mixins的方法
2017/09/12 Javascript
angular的输入和输出的使用方法
2018/09/22 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
[25:45]2018DOTA2亚洲邀请赛4.5SOLO赛 Sylar vs Paparazi
2018/04/06 DOTA
使用Python保存网页上的图片或者保存页面为截图
2016/03/05 Python
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
全面了解python中的类,对象,方法,属性
2016/09/11 Python
python爬虫框架scrapy实战之爬取京东商城进阶篇
2017/04/24 Python
Java分治归并排序算法实例详解
2017/12/12 Python
对Python3中的print函数以及与python2的对比分析
2018/05/02 Python
python调用Matplotlib绘制分布点图
2019/10/18 Python
python常用排序算法的实现代码
2019/11/08 Python
新英格兰最大的特色礼品连锁店:The Paper Store
2018/07/23 全球购物
品质主管的岗位职责
2013/12/04 职场文书
《时代广场的蟋蟀》读后感:真挚友情,温暖世界!
2020/01/08 职场文书
win11如何查看端口是否被占用? Win11查看端口是否占用的技巧
2022/04/05 数码科技
HTML页面点击按钮关闭页面的多种方式
2022/12/24 HTML / CSS