JavaScript反彈動(dòng)畫(huà)效果的實(shí)現(xiàn)代碼
代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#box{
width:200px;
height:200px;
position: absolute;
top:0;
left:200px;
background:lightblue;
}
.btn{
position:absolute;
top:200px;
left:100px;
height:50px;
}
.btn input{
display:inline-block;
margin-left:50px;
outline: none;
width:100px;
height:50px;
border:1px solid green;
cursor:pointer;
}
</style>
</head>
<body>
<div id='box'></div>
<div class='btn'>
<input type="button" value='向左' id='btnLeft'>
<input type="button" value='向右' id='btnRight'>
</div>
<script>
var oBox = document.getElementById("box");
var minLeft = 0;
var maxLeft = utils.win('clientWidth')-oBox.offsetWidth;
var step = 5;
var timer = null;
function move(target){
//target:告訴我要運(yùn)動(dòng)的目標(biāo)位置
window.clearTimeout(timer);
var curLeft = utils.css(oBox,"left");
if(curLeft<target){//向右走
if(curLeft+step>target){//邊界
utils.css(oBox,"left",target);
return;
}
curLeft+=step;
utils.css(oBox,"left",curLeft)
}else if(curLeft>target){//向左走
if(curLeft-step<target){//邊界
utils.css(oBox,"left",target);
return;
}
curLeft-=step;
utils.css(oBox,"left",curLeft)
}else{//不需要運(yùn)動(dòng)
return;
}
// timer = window.setTimeout(move,10)//這里有一個(gè)問(wèn)題,點(diǎn)擊按鈕第一次target的值是有的,但是第二次通過(guò)setTimeout執(zhí)行的時(shí)候沒(méi)有給target進(jìn)行傳值。是undefined
timer = window.setTimeout(function(){
move(target);
},10)//這樣使用匿名函數(shù)包裹一下,就解決了上面的問(wèn)題,但是這樣寫(xiě)性能不好,因?yàn)槊恳淮蔚竭_(dá)時(shí)間的時(shí)候,都需要執(zhí)行一次匿名函數(shù)(形成一個(gè)私有的作用域),在匿名函數(shù)中再執(zhí)行move,但是move中需要用到的數(shù)據(jù)值在第一次執(zhí)行的move方法中,需要把匿名函數(shù)形成的這個(gè)私有的作用域作為跳板找到之前的,這樣就導(dǎo)致了匿名函數(shù)形成的這個(gè)私有的作用域不能銷(xiāo)毀
}
document.getElementById('btnLeft').onclick = function(){
move(minLeft)
}
document.getElementById('btnRight').onclick = function(){
move(maxLeft)
}
</script>
</body>
</html>
為了解決上面性能不好的問(wèn)題,下面是一個(gè)優(yōu)化后的代碼:里面在使用一個(gè)函數(shù)包裹,這樣就只有move函數(shù)創(chuàng)建的一個(gè)私有作用域沒(méi)有銷(xiāo)毀,等到_move執(zhí)行完畢,move就自然會(huì)進(jìn)行銷(xiāo)毀。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#box{
width:200px;
height:200px;
position: absolute;
top:0;
left:200px;
background:lightblue;
}
.btn{
position:absolute;
top:200px;
left:100px;
height:50px;
}
.btn input{
display:inline-block;
margin-left:50px;
outline: none;
width:100px;
height:50px;
border:1px solid green;
cursor:pointer;
}
</style>
</head>
<body>
<div id='box'></div>
<div class='btn'>
<input type="button" value='向左' id='btnLeft'>
<input type="button" value='向右' id='btnRight'>
</div>
<script>
var oBox = document.getElementById("box");
var minLeft = 0;
var maxLeft = utils.win('clientWidth')-oBox.offsetWidth;
var step = 5;
var timer = null;
function move(target){
//target:告訴我要運(yùn)動(dòng)的目標(biāo)位置
_move();
function _move(){
window.clearTimeout(timer);
var curLeft = utils.css(oBox,"left");
if(curLeft<target){//向右走
if(curLeft+step>target){//邊界
utils.css(oBox,"left",target);
return;
}
curLeft+=step;
utils.css(oBox,"left",curLeft)
}else if(curLeft>target){//向左走
if(curLeft-step<target){//邊界
utils.css(oBox,"left",target);
return;
}
curLeft-=step;
utils.css(oBox,"left",curLeft)
}else{//不需要運(yùn)動(dòng)
return;
}
timer = window.setTimeout(_move,10);
}
}
document.getElementById('btnLeft').onclick = function(){
move(minLeft)
}
document.getElementById('btnRight').onclick = function(){
move(maxLeft)
}
</script>
</body>
</html>
注意:為了讓當(dāng)前的元素在同一時(shí)間只運(yùn)行一個(gè)動(dòng)畫(huà)(下一個(gè)動(dòng)畫(huà)開(kāi)始的時(shí)候首先把上一個(gè)動(dòng)畫(huà)的定時(shí)器清除掉):保證當(dāng)前元素所有動(dòng)畫(huà)接收定時(shí)器返回值的那個(gè)變量需要共享,有兩種方式:1、全局接收(例如上面的代碼 var timer = null)2、給元素增加自定義屬性(如下圖所示)

總結(jié):通過(guò)以上可以得出動(dòng)畫(huà)優(yōu)化的四條規(guī)則:
1、邊界判斷加步長(zhǎng)
2、清除沒(méi)有用的定時(shí)器
3、在外層函數(shù)需要傳參的時(shí)候,可以在里面在嵌套一層函數(shù),避免作用域的累積。
4、把定時(shí)器的返回值存儲(chǔ)在元素的自定義屬性上,防止全局變量沖突和同一時(shí)間多個(gè)動(dòng)畫(huà)執(zhí)行
以上所述是小編給大家介紹的JavaScript反彈動(dòng)畫(huà)效果的實(shí)現(xiàn)代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- JS實(shí)現(xiàn)小球的彈性碰撞效果
- js實(shí)現(xiàn)簡(jiǎn)單的碰壁反彈效果
- Js實(shí)現(xiàn)簡(jiǎn)單的小球運(yùn)動(dòng)特效
- 用js實(shí)現(xiàn)小球的自由移動(dòng)代碼
- javascript動(dòng)畫(huà)之圓形運(yùn)動(dòng),環(huán)繞鼠標(biāo)運(yùn)動(dòng)作小球
- JS完成畫(huà)圓圈的小球
- JS小球拋物線(xiàn)軌跡運(yùn)動(dòng)的兩種實(shí)現(xiàn)方法詳解
- JS實(shí)現(xiàn)碰撞檢測(cè)的方法分析
- JS實(shí)現(xiàn)簡(jiǎn)單的浮動(dòng)碰撞效果示例
- 原生JS實(shí)現(xiàn)多個(gè)小球碰撞反彈效果示例
相關(guān)文章
帝國(guó)cms首頁(yè)列表頁(yè)實(shí)現(xiàn)點(diǎn)贊功能
這篇文章主要介紹了帝國(guó)cms首頁(yè)列表頁(yè)實(shí)現(xiàn)點(diǎn)贊功能的相關(guān)資料,需要的朋友可以參考下2017-10-10
詳細(xì)分析單線(xiàn)程JS執(zhí)行問(wèn)題
給大家詳細(xì)講解一下單線(xiàn)程javascript的執(zhí)行問(wèn)題,以及通過(guò)實(shí)例分析用法。2017-11-11
固定網(wǎng)頁(yè)背景圖同時(shí)保持圖片比例的思路代碼
代碼功能:背景圖片固定,隨窗口大小改變而改變大小,保持比例不變而縮放,有此需求的朋友可以參考下2013-08-08
jQuery實(shí)現(xiàn)手風(fēng)琴特效
這篇文章主要為大家詳細(xì)介紹了前端js實(shí)現(xiàn)手風(fēng)琴效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-01-01

