使用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查看html源文件
Nov 08 Javascript
HTML颜色选择器实现代码
Nov 23 Javascript
location对象的属性和方法应用(解析URL)
Apr 12 Javascript
javascript 函数及作用域总结介绍
Nov 12 Javascript
JavaScript实现基于Cookie的存储类实例
Apr 10 Javascript
javascript弹出窗口实现代码
Nov 12 Javascript
javascript设计简单的秒表计时器
Sep 05 Javascript
JavaScript中清空数组的方法总结
Dec 02 Javascript
微信小程序 支付简单实例及注意事项
Jan 06 Javascript
原理深度解析Vue的响应式更新比React快
Apr 04 Javascript
vue中后端做Excel导出功能返回数据流前端的处理操作
Sep 08 Javascript
vue自定义组件实现双向绑定
Jan 13 Vue.js
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中使用接口实现工厂设计模式的代码
2012/06/17 PHP
PHP如何使用Memcached
2016/04/05 PHP
js 实现无缝滚动 兼容IE和FF
2009/07/15 Javascript
Javascript 事件流和事件绑定
2009/07/16 Javascript
javascript事件问题
2009/09/05 Javascript
TBCompressor js代码压缩
2011/01/05 Javascript
基于jQuery的倒计时实现代码
2012/05/30 Javascript
JS修改css样式style浅谈
2013/05/06 Javascript
js用正则表达式来验证表单(比较齐全的资源)
2013/11/17 Javascript
浅谈JavaScript数据类型及转换
2015/02/28 Javascript
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
微信小程序  简单实例(阅读器)的实例开发
2016/09/29 Javascript
详解用node-images 打造简易图片服务器
2017/05/08 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
JavaScript中Object值合并方法详解
2017/12/22 Javascript
详解Puppeteer前端自动化测试实践
2019/02/21 Javascript
自定义javascript验证框架示例【附源码下载】
2019/05/31 Javascript
jquery.pager.js分页实现详解
2019/07/29 jQuery
你不知道的 TypeScript 高级类型(小结)
2020/08/28 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
2020/11/16 Javascript
JS实现京东商品分类侧边栏
2020/12/11 Javascript
[02:00]DAC2018主宣传片——龙征四海,剑问东方
2018/03/20 DOTA
python之模拟鼠标键盘动作具体实现
2013/12/30 Python
Python中getpass模块无回显输入源码解析
2018/01/11 Python
解决phantomjs截图失败,phantom.exit位置的问题
2018/05/17 Python
windows python3安装Jupyter Notebooks教程
2020/04/13 Python
keras-siamese用自己的数据集实现详解
2020/06/10 Python
python获取整个网页源码的方法
2020/08/03 Python
HTML5混合开发二维码扫描以及调用本地摄像头
2017/12/27 HTML / CSS
化学相关工作求职信
2013/10/02 职场文书
毕业大学生自荐信
2014/06/17 职场文书
廉洁自律承诺书2015
2015/01/22 职场文书
goland 恢复已更改文件的操作
2021/04/28 Golang
golang fmt格式“占位符”的实例用法详解
2021/07/04 Golang
详解JSON.parse和JSON.stringify用法
2022/02/18 Javascript
win10滚动条自动往上跑怎么办?win10滚动条自动往上跑的解决方法
2022/08/05 数码科技