JavaScript运动基础,常用函数封装

来源:互联网 发布:不用实名注册的域名 编辑:程序博客网 时间:2024/05/16 07:10

要求:点按钮,红色div右移

<style>    #div1 {        width:200px;        height:200px;        background:red;        position:absolute;        top:50px;        left:0;    }</style><div id="div1"></div><input type="button" value="start" /><script>    oBtn.onclick = function() {        function startMove() {            var oDiv = document.getElementById('div1');            setInterval(function(){                oDiv.style.left = oDiv.offsetLeft + 10 + 'px';            }, 30);        }    };</script>
但是,有问题,不能停下来,要求能停下来
var timer = null;var speed = 7;oBtn.onclick = function() {    function startMove() {        var oDiv = document.getElementById('div1');        timer = setInterval(function() {            if (oDiv.offsetLeft == 300) {                clearInterval(timer);            }        oDiv.style.left = oDiv.offsetLeft + speed +'px';        }, 30);    }};
很显然,speed为10没有问题,如果为7呢?,根本停不下来,因为7,14,21,……..280,287,294,301….直接跳过300,所以,程序中==300是不合理的应该修改为 ‘>=300’,虽然停下来,但是,停的位置是301,不精准。
var timer = null;var speed = 7;oBtn.onclick = function() {    function startMove() {        var oDiv = document.getElementById('div1');        timer = setInterval(function() {            if (oDiv.offsetLeft >= 300) {                clearInterval(timer);            }        oDiv.style.left = oDiv.offsetLeft + speed +'px';        }, 30);    }};

现在,红色div已经到了目的地,再点击,应该不再移动,但是,你再点击按钮,奇怪,居然还是右移了一下,每次点击都还移动一次,准确说,又移动了7px,为什么?因为,你点击一次,就启动一次定时器,但你会问,我做了判断,大于300了就停止定时器了。但是,你认真思考,你停的定时器只是从下一次不开始执行了,但是本次的还是要执行完。解决方案很简单,就是下面移动的那一句不让执行了,加个else:

var timer = null;var speed = 7;oBtn.onclick = function() {    function startMove() {        var oDiv = document.getElementById('div1');        timer = setInterval(function() {            if (oDiv.offsetLeft >= 300) {                clearInterval(timer);            } else {                oDiv.style.left = oDiv.offsetLeft + speed +'px';            }        }, 30);    }};

现在将speed改为1,我连续多点几次启动按钮,你会发现,红色div走的越来越快,因为,你每点一次,就启动一个定时器,点五次,就五个,五个同时走,就相当于5倍的speed,我们需要保证只有一个定时器在工作怎么解决?启动定时器之前清理掉之前的即可!

var timer = null;var speed = 7;oBtn.onclick = function() {    function startMove() {        var oDiv = document.getElementById('div1');        clearInterval(timer);        timer = setInterval(function() {            if (oDiv.offsetLeft >= 300) {                clearInterval(timer);            } else {                oDiv.style.left = oDiv.offsetLeft + speed +'px';            }        }, 30);    }};

总结一下:

  1. 在运动开始时,关闭已有定时器,免得多个定时器同时工作
  2. 把运动和停止隔开(if/else),把运动和停止分开,不能同时发生

例子1–侧边栏

就是分享,鼠标移到最左边出现一个侧边栏,移走鼠标,侧边栏又消失

<style>    #div1 {        width:150px;        height:200px;        background:green;        position:absolute;        left:-150px;/*隐藏,改为0就出来了*/    }    #div1 span {        position:absolute;        widht:20px;        height:60px;        line-heigth:20px;        background:blue;        right:-20px;        top:70px;    }</style><div id="div1">    <span>分享到</span></div><script>    var oDiv = document.getElementById('div1');    var timer = null;    window.onload = function() {        oDiv.onmouseover = function() {            outspreadMove();        };        oDiv.onmouseout = function() {            shinkspeadMove();        };    };    function outspreadMove() {        clearInterval(timer);        timer = setInterval(function() {            if(oDiv.offset == 0) {                clearInterval(timer);            } else {                oDiv.style.left = oDiv.offsetLeft + 10 + 'px';            }        },30);    }    function shrinkspreadMove() {        clearInterval(timer);        timer = setInterval(function() {            if(oDiv.offsetLeft == -150) {                clearInterval(timer);            } else {                oDiv.style.left = oDiv.offsetLeft - 10 + 'px';            }        },30);    }</script>

优化,合并

以上2个move函数,长得那么像,可以合并的,你看看两个函数,不一样的地方,一个(0,-150),一个(10,-10),不一样的地方当参数传过来,遵循这个原则即可

<script>    function fnMove(speed, iTarget) {        clearInterval(timer);        timer = setInterval(function() {            if(oDiv.offsetLeft == iTarget) {              clearInterval(timer);              } else {               oDiv.style.left = oDiv.offsetLeft + speed + 'px'             }        }, 30)    }    //Invoke    oDiv.onmouseover = function() {        fnMove(10, 0);    };    oDiv.onmouseout = function() {        fnMove(-10, -150);    };</script>

进一步优化

两个函数功能一样,参数越少,用的越好,我希望能减少一个参数,上面fnMove(),两个参数,一个速度,一个目的地。就像打出租车,你只要说你去望京就行了,哪有告诉出租车你要开多快速度的?所以,要把speed这个参数干掉。

left: 30 iTarget:300 需要右走(速度正)
left: 600 iTarget:50 需要左走(速度负)
<script>    function fnMove(iTarget) {        var speed = 0;        if(oDiv.offsetLeft > iTarget) {            speed = -10;        } else {            speed = 10;        }        clearInterval(timer);        timer = setInterval(function() {            if(oDiv.offsetLeft == iTarget) {              clearInterval(timer);              } else {               oDiv.style.left = oDiv.offsetLeft + speed + 'px'             }        }, 30)    }    //Invoke    oDiv.onmouseover = function() {        fnMove(0);    };    oDiv.onmouseout = function() {        fnMove(-150);    };</script>

淡入淡出的图片

#div {    width:200px;    height:200px;    background:red;    filter:alpha(opacity:30);    opacity:0.3;}<div id="div1"></div><script>    var alpha = 30;    var timer = null;    function startMove(iTarget) {        var oDiv = document.getElementById('div1');        clearInterval(timer);        timer = setInterval(function() {            var speed = 0;            if(alpha < iTarget) {                speed = 10;            } else {                speed = -10;            }            if(alpha == iTarget) {                clearInterval(timer);            } else {                alpha += speed;//目前为止,仍然看不到物体透明度的变化,因为只是alpha变量在变化                oDiv.style.filter = 'alpha(opacity:'+alpha+')';                oDiv.style.opacity = alpha/100;//兼容火狐、Chrome            }        }, 30)    }    window.onload = function() {        var oDiv = document.getElementById('div1');        oDiv.onmouseover = function() {            startMove(100);        };        oDiv.onmouseout = function() {            startMove(30);        };    };</script>
注意:opacity设置不透明度,所有浏览器都支持IE8以及更早版本支持替代的filter属性,例如:filter:Alpha(opacity=50)。
1 0