實現vue項目下多元素限定邊界的拖拽功能

要求:實現多個元素在限定的範圍內自由拖拽

(除vue的其他項目也可以用,稍微修改下即可)

拖拽原理:

onmousedown(鼠標左鍵點下),onmousemove(鼠標移動),onmouseup(鼠標鬆開)三個事件的順序執行,在移動過程中去獲取需要定位的值,然後改變該元素定位的left,top值。

限定邊界原理:

做相應的邊界判斷

直接上代碼,代碼註釋的非常詳細:

<template>
	<div>
		<div id="dragBox">
			<div v-for="(item,index) in list" :key="index" class="box1" :style="{left:(index*60 +50)+'px'}"  :id="'a'+index" @click="btnclick(index)">點擊{{index}}</div>
		</div>
	</div>
</template>

<script>
	export default{
		data() {
			return{
				list:[1,2,3,4,5],
				isDrag: false
			}
		},
		created() {
		},
		mounted() {
		},
		methods:{
			// 點擊元素事件
			btnclick(index) {
				// 打印ID值
				console.log('a'+index)
				// 對多個元素綁定拖拽事件,要先點擊,然後才能拖拽(先點擊獲取元素對象)
				var obj=document.getElementById("a"+index)
				var obox=document.getElementById("dragBox");
				console.log('clientWidth', obox.clientWidth)
				console.log('box.clientWidth', obj.clientWidth)
				// 爲每個元素加入拖拽事件
				this.drag(obj,obox)
			},
			drag(box,obox) {
				  var disX
				  var disY
				  var that = this
				  // 鼠標左鍵按下事件
				  box.οnmοusedοwn=function(ev){
				    var oEvent=ev||event
					// clientX,clientY:鼠標點擊位置到瀏覽器可視區域x,y距離
					// offsetLeft,offsetTop:元素距離父級元素的偏移距離
				    disX=oEvent.clientX - box.offsetLeft
				    disY=oEvent.clientY - box.offsetTop
					that.isDrag = true
					console.log('isDrag', that.isDrag)
					console.log('clientX', oEvent.clientX)
					console.log('clientY', oEvent.clientY)
					console.log('offsetLeft', box.offsetLeft)
					console.log('offsetTop', box.offsetTop)
					console.log('disX', disX)
					console.log('disY', disY)
					// 鼠標移動事件
				    document.οnmοusemοve=function(ev){
						// 加入該判斷拖拽更流暢
						if (that.isDrag) {
							var oEvent=ev||event
							  // 計算點擊元素到父級元素的定位top,left距離
							  var l=oEvent.clientX-disX
							  var t=oEvent.clientY-disY
							  // 設置拖拽邊界(限定在瀏覽器可視區域(空白區域)之內)
							  // 限定左邊界
							  // if(l<0){
							  //   l=0
							  // }else if(l>document.documentElement.clientWidth-box.offsetWidth){
							  //   限定右邊界
							  //   l=document.documentElement.clientWidth-box.offsetWidth
							  // }
							  // 限定上邊界
							  // if(t<0){
							  //   t=0
							  // }else if(t>document.documentElement.clientHeight-box.offsetHeight){
							  //   限定下邊界
							  //   t=document.documentElement.clientHeight-box.offsetHeight
							  // }
							  /** 限定拖拽範圍,限定拖拽元素在指定的範圍內 */
							  // 限定左邊界和上邊界
							   if(l<0){
								  l=0;
								}
								if(t<0){
								  t=0;
								}
								// 限定右邊界的距離(當l=父元素寬-子元素寬時,剛好子元素放在父元素最右邊)
							   if(l>obox.clientWidth - box.clientWidth){
								  l=obox.clientWidth - box.clientWidth
								}
								// 限定下邊界的距離(當t=父元素高-子元素高時,剛好子元素放在父元素最下邊)
								if(t>obox.clientHeight - box.clientHeight){
								   t = obox.clientHeight - box.clientHeight
								}
							  box.style.left=l+'px'
							  box.style.top=t+'px'
							}
						}
				    document.οnmοuseup=function(){
					  that.isDrag = false
				      document.οnmοusemοve=null
				      document.οnmοuseup=null //鼠標擡起來後,onmouseup事件本身也沒意義了,所以最好清理掉
				    }
				    return false //阻止默認行爲,空的div在低版本ff下,第二次拖動手型會變異常
				  }
		}
	}
}	
</script>

<style>
	#dragBox{
		position: relative;
		width:500px;
		height:500px;
		border:1px solid red;
		margin-left:200px;
	}
	.box1{
		width:50px;
		height:50px;
		background:#13CE66;
		/* 一定要設置定位,拖拽就是根據定位實現的 */
		position: absolute;
		top:200px;
	}
</style>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章