要求:實現多個元素在限定的範圍內自由拖拽
(除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>