在Vue里提倡操作虚拟dom尽量不操作真实是dom。但在频繁操作dom的情况下显然体验不好,使用Js操作真实dom来实现div的随意拖拽。
这里为了复用,写成了指令,方便其他页面使用,直接调指令,不需要重复写。
pc端:
<template>
<div class="ha">
<div class="box" v-wahaha></div>
</div>
</template>
<script>
export default {
data(){
return{x:"",y:"",}
},
mounted(){
let box = document.querySelector('.box')
let move = JSON.parse(window.localStorage.getItem("move"))
box.style.left = move.x
box.style.top = move.y
},
directives:{
wahaha(el,binding){
el.onmousedown = function(ev){
var x = ev.clientX - el.offsetLeft;
var y = ev.clientY - el.offsetTop;
el.onmousemove = function(ev){
window.localStorage.removeItem("move")
this.x = ev.clientX - x + 'px';
this.y = ev.clientY - y + "px" ;
el.style.left = this.x
el.style.top = this.y
window.localStorage.setItem("move",JSON.stringify({x:this.x,y:this.y}))
}
// window.localStorage.setItem("move",this.x) 拿不到
el.onmouseup = function(ev){
el.onmousemove = el.onmouseup = null;
}
return false;
}
}
}
}
</script>
<style scoped>
.box{
width: 200px;
height: 200px;
position: absolute;
top: 100px;
left: 100px;
background: red;
}
</style>
用到的div直接加上 V-wahaha指令即可。
pc端可能存在浏览器兼容,可根据自己的需要优化。
图解:
移动端:
代码复制直接用。
<template>
<div >
<div id="box" v-wahaha></div>
</div>
</template>
<script type="text/javascript">
export default {
mounted(){
this.$nextTick(()=>{
var box = document.getElementById('box')
var move = JSON.parse(window.localStorage.getItem("move"));
box.style.left = `${move.x}px`;
box.style.top = `${move.y}px`;
})
},
directives:{
drag(el,binding){
var lenX //定义x轴相对手指点击位置距离盒子元素左边框距离
var lenY //定义y轴相对手指点击位置距离盒子元素上边框距离
var maxW //定义盒子在x轴上可移动的最大值
var maxH //定义盒子在y轴上可移动的最大值
el.addEventListener('touchstart',function(e){//按下去时
maxW = e.srcElement.offsetParent.clientWidth-el.offsetWidth;
maxH = e.srcElement.offsetParent.clientHeight-el.offsetHeight;
// maxW = document.body.clientWidth/clientHeight - el.offsetWidth;
var ev = e || window.event;
var touch = ev.targetTouches[0];
lenX = touch.clientX - el.offsetLeft;
lenY = touch.clientY - el.offsetTop;
el.addEventListener("touchmove",defaultEvent,false);//注释后 靠边弹性返回
window.localStorage.removeItem("move")
})
el.addEventListener('touchmove',function(e){//拖动时
var ev = e || window.event;
var touch = ev.targetTouches[0];
var left = touch.clientX - lenX;
var top = touch.clientY - lenY;
if(left<0){
left=0;
}else if (left>=maxW) {
left=maxW;
}
if(top <0){
top =0;
}else if (top >=maxH) {
top =maxH;
}
el.style.left = left + 'px';
el.style.top = top + 'px';
window.localStorage.setItem("move",JSON.stringify({x:left,y:top}))
})
el.addEventListener('touchend',function(){ //松开时
document.removeEventListener("touchmove",defaultEvent);
})
function defaultEvent(e) {
e.preventDefault();
}
}
},
}
</script>
<style media="screen">
#box {
width: 100px;
height: 100px;
left: 10px;
top: 10px;
background:pink;
position: absolute;
}
</style>
图解:
以上封的是局部指令,只可在当前页面使用指令。
以下是全局指令,可在所有页面使用指令。
Vue.directive("wahaha",
(el,binding)=>{
var lenX //定义x轴相对手指点击位置距离盒子元素左边框距离
var lenY //定义y轴相对手指点击位置距离盒子元素上边框距离
var maxW //定义盒子在x轴上可移动的最大值
var maxH //定义盒子在y轴上可移动的最大值
el.addEventListener('touchstart',function(e){//按下去时
maxW = e.srcElement.offsetParent.clientWidth-el.offsetWidth;
maxH = e.srcElement.offsetParent.clientHeight-el.offsetHeight;
// maxW = document.body.clientWidth/clientHeight - el.offsetWidth;
var ev = e || window.event;
var touch = ev.targetTouches[0];
lenX = touch.clientX - el.offsetLeft;
lenY = touch.clientY - el.offsetTop;
el.addEventListener("touchmove",defaultEvent,false);//注释后 靠边弹性返回
window.localStorage.removeItem("move")
})
el.addEventListener('touchmove',function(e){//拖动时
var ev = e || window.event;
var touch = ev.targetTouches[0];
var left = touch.clientX - lenX;
var top = touch.clientY - lenY;
if(left<0){
left=0;
}else if (left>=maxW) {
left=maxW;
}
if(top <0){
top =0;
}else if (top >=maxH) {
top =maxH;
}
el.style.left = left + 'px';
el.style.top = top + 'px';
window.localStorage.setItem("move",JSON.stringify({x:left,y:top}))
})
el.addEventListener('touchend',function(){ //松开时
document.removeEventListener("touchmove",defaultEvent);
})
function defaultEvent(e) {
e.preventDefault();
}
}
)
有好的优化的欢迎指出,有帮助到就给个支持吧。。。。。