一.用callback形式回调
const walk=(target,direction,distance,callback)=>{
setTimeout(()=>{
//parseInt() 10代表只能是10的倍数
let currentLeft=parseInt(target.style.left,10)
let currentTop=parseInt(target.style.top,10)
console.info('currentLeft',currentLeft,'distance',distance,'currentTop',currentTop)
const shouldFinish=(direction==='left'&¤tLeft===-distance)||(direction==='top'&¤tTop===-distance)
//本次移动结束,继续下一次移动
if(shouldFinish){
callback&&callback()
}else{
if(direction==='left'){
currentLeft--
target.style.left=`${currentLeft}px`
}else if(direction==='top'){
currentTop--
target.style.top=`${currentTop}px`
}
walk(target,direction,distance,callback)
}
},1000)
}
//二 用Promise方案解决
const walkExtend=(target,direction,distance)=>
new Promise((resolve,reject)=>{
const innerWalk=()=>{
setTimeout(()=>{
let currentLeft=parseInt(target.style.left,10)
let currentTop=parseInt(target.style.top,10)
console.info('currentLeft',currentLeft,'distance',distance,'currentTop',currentTop)
const shouldFinish=(direction==='left'&¤tLeft===-distance)||(direction==='top'&¤tTop===-distance)
//本次移动结束,继续下一次移动
if(shouldFinish){
//任务结束
resolve()
}else{
if(direction==='left'){
currentLeft--
target.style.left=`${currentLeft}px`
}else if(direction==='top'){
currentTop--
target.style.top=`${currentTop}px`
}
innerWalk()
}
},20)
}
innerWalk()
})
三.html调用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="./yibu.js"></script>
</head>
<style>
#man{
width:10px;
height:10px;
background-color: skyblue;
}
</style>
<body>
<div id="man"></div>
<script>
window.addEventListener("load",function(){
const target=document.querySelectorAll('#man')[0]
target.style.cssText=`position:absolute;left:0px;top:0px;`
//用callback解决
walk(target,'left',10,()=>{
walk(target,'top',50,()=>{
walk(target,'left',30,Function.prototype)
})
})
//用promise解决
walkExtend(target,'left',20).then(()=>
walkExtend(target,'top',50)).then(()=>
walkExtend(target,'left',30))
//用Generator解决
function *taskGenerator(){
yield walkExtend(target,'left',20)
yield walkExtend(target,'top',50)
yield walkExtend(target,'left',30)
}
const gen=taskGenerator()
gen.next() //要手动执行next函数
//用async await解决
const task=async function(){
await walkExtend(target,'left',20)
await walkExtend(target,'top',50)
await walkExtend(target,'left',30)
}
task()
})
</script>
</body>
</html>
缺点:跑出屏幕外并没有做处理。简化版本初始值都设为0