JavaScript元素拖拽路徑回放效果

admin發表於2018-12-01

拖拽是常見效果,有時可能有這樣的需求,那就是可以使元素能夠按照拖拽的路徑原路返回。

下面通過程式碼例項配合詳細的註釋,介紹一下如何實現此功能。

程式碼如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style type="text/css">
#thediv{
  width:60px;
  height:60px;
  background-color:#ccc;
  display:block;
  font-size:12px;
  position:absolute;
}
#reback{
  position:absolute;
  margin-top:100px;
  color:yellow;
  font-size:12px;
  background-color:red;
}
</style>
<script type="text/javascript">
window.onload=function(){ 
  var obj=document.getElementById("thediv"); 
  var disX=disY=0; 
  var dragIf=false; 
 
  var position=[{x:obj.offsetLeft,y:obj.offsetTop}];
  var olink=document.getElementsByTagName("a")[0]; 
 
  obj.onmousedown=function(event){ 
    var event=event||window.event; 
    disX=event.clientX-obj.offsetLeft;
    disY=event.clientY-obj.offsetTop; 
    dragIf=true;
    position.push({x:obj.offsetLeft,y:obj.offsetTop});
    return false; 
  }; 
 
  document.onmousemove=function(event){ 
    if(!dragIf) return;
    var event=event||window.event; 
    var nowX=event.clientX-disX;
    var nowY=event.clientY-disY; 
         
    var maxX=document.documentElement.clientWidth-obj.offsetWidth;
    var maxY=document.documentElement.clientHeight-obj.offsetHeight; 
         
    nowX=nowX<0?0:nowX;
    nowY=nowY<0?0:nowY; 
    nowX=nowX>maxX?maxX:nowX; 
    nowY=nowY>maxY?maxY:nowY; 
 
    obj.style.marginTop=obj.style.marginLeft=0; 
    obj.style.left=nowX+"px";
    obj.style.top=nowY+"px"; 
    position.push({x:nowX,y:nowY});
    obj.innerHTML="X:"+nowX+"<br/>Y:"+nowY;
    return false; 
  }; 
  document.onmouseup=function(){ 
    dragIf=false;
    obj.innerHTML="X:"+obj.offsetLeft+"<br/>Y:"+obj.offsetTop; 
  }; 
  olink.onclick=function(){ 
    if(position.length==1) return;
    var timer=setInterval(function(){ 
      var oPos=position.pop(); 
      obj.innerHTML="X:"+oPos.x+"<br/>Y:"+oPos.y; 
      oPos?(obj.style.left=oPos.x+"px",obj.style.top=oPos.y+"px"):clearInterval(timer);
    }, 30); 
    return false; 
  }; 
};
</script>
</span>
</head>
<body>
<div id="thediv"></div>
<a href="#" id="reback">回放</a>
</body>
</html>

點選按鈕可以使div元素按照原路返回,並且在div中顯示相應的座標。

一.實現原理:

當拖動div的時候,將相應座標存放於陣列中,回放的時候按照這個座標原路返回即可。

二.程式碼註釋:

(1).window.onload=function(){},當文件結構完全載入完畢再去執行函式中的程式碼。

(2).var obj=document.getElementById("thediv"),獲取div物件元素。

(3).var disX=disY=0,宣告兩個變數並賦初值0,儲存當前滑鼠指標距離div的邊緣的距離。

(4).var dragIf=false,宣告一個變數,並賦初值為false,標識當前div是否可以拖動。

(5).var position=[{x: obj.offsetLeft,y: obj.offsetTop}],獲取div元素最初在頁面中的座標。

(6).var olink=document.getElementsByTagName("a")[0],獲取連結按鈕物件。

(7).obj.onmousedown=function(event){},為div註冊mousedown事件處理函式。

(8).var event=event||window.event,獲取事件物件,採用了相容性寫法。

(9).disX=event.clientX-obj.offsetLeft,獲取當滑鼠按下時,滑鼠指標距離div左邊緣的距離。

(10).disY=event.clientY-obj.offsetTop,獲取當滑鼠按下時,滑鼠指標距離div上邊緣的距離。

(11).dragIf=true,設定為true,也就是當滑鼠按下的時候,div就可以被拖動了。

(12).position.push({x: obj.offsetLeft,y: obj.offsetTop}),將一個物件存入陣列,物件具有兩個屬性,分別是div元素d左邊緣距離頁面左端的距離和上邊緣距離頁面上端的距離。

(13).return false,為了防止事件冒泡。

(14).document.onmousemove=function(event){},為document註冊mousemove事件處理函式,很多朋友可能會有這樣的疑問,為什麼不是直接註冊在div元素上,因為在拖動的過程中,滑鼠指標可能會滑出div元素,拖動就會失效了。

(15).if(!dragIf) return,如果dragIf為false,那就是不允許拖動,直接跳出函式。

(16).var event=event||window.event,獲取事件物件,相容性寫法。

(17).var nowX=event.clientX-disX,獲取div元素在瀏覽器客戶區中的水平座標。

(18).var nowY=event.clientY-disY,獲取div元素在瀏覽器客戶區的垂直座標。

(19).var maxX=document.documentElement.clientWidth-obj.offsetWidth,獲取div水平最大座標值。

(20).var maxY=document.documentElement.clientHeight-obj.offsetHeight,獲取div垂直最大座標值。

(21).nowX=nowX<0?0:nowX,如果nowX值小於0,就設定其為零,防止超出頁面邊界。

(22).nowY=nowY<0?0:nowY,和上面是同樣的道理。

(23).nowX=nowX>maxX?maxX:nowX,nowx超出最大限制,將其設定為最大限制值,防止出界。

(24).nowY=nowY>maxY?maxY:nowY,和上面是同樣的道理。

(25).obj.style.marginTop=obj.style.marginLeft=0,將div外邊距設定為0,已經在css設定,沒有必要。

(26).obj.style.left=nowX+"px",設定元素的left屬性值。

(27).obj.style.top=nowY+"px",設定元素的top屬性值。

(28).position.push({x:nowX,y:nowY}),將當前div的座標追加到陣列元素中。

(29).obj.innerHTML="X:"+nowX+"<br/>Y:"+nowY在div中顯示當前元素的座標。

(30).return false,完全可以不要。

(31).document.onmouseup=function(){},為document註冊mouseup事件處理函式。

(32).dragIf=false,設定為false,也就是div無法拖動。

(33).obj.innerHTML="X:"+obj.offsetLeft+"<br/>Y:"+obj.offsetTop,將當前座標值寫入div。

(34).olink.onclick=function(){},為連結按鈕註冊點選事件處理函式。

(35).if(position.length==1) return,如果陣列只有一個座標物件,說明div沒有拖動,直接跳出函式。

(36).var timer=setInterval(function(){},30),每隔30毫秒執行一次函式。

(37).var oPos=position.pop(),刪除陣列的最後一個元素,然後返回此元素。

(38).obj.innerHTML="X:"+oPos.x+"<br/>Y:"+oPos.y,將座標寫入div。

(39).oPos?(obj.style.left=oPos.x+"px",obj.style.top=oPos.y+"px"):clearInterval(timer),如果陣列元素依然存在,那麼就設定座標,否則停止定時器函式的執行。

相關文章