一个简单的demo 能实现复制拖拽

200 阅读2分钟

一个简单的demo 能实现复制拖拽

<template>
  <div class="drag" ref="drag">
    <!-- <h2>使用拖拽实现移动和复制功能</h2> -->
    <div ref="targtBox" draggable="true" id="copy" @dragstart='handler_dragstart' @dragend='dragend'>要复制的元素</div>
    <div ref="back_box" id="copyTarget" @dragover='hander_dragover' @drop='handler_drop'>
      <div class="targtBoxicon" draggable="true" @dragstart='dragstart($event,item)' @dragend='dragend_handler($event,item)' v-for="item,i in list" :key="i" :style="`left:${item.left}%;top:${item.top}%`">
        {{i}}
      </div>
    </div>


  </div>
</template>


<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String,
  },
  data() {
    return {
      startclientX_c: 0,
      startclientY_c: 0,
      bodyWidth: 0,//浏览器可视区域的宽高
      bodyHeight: 0,
      initWidth: 0, // 父元素的宽-自适应值
      initHeight: 0, // 父元素的高-自适应值
      startclientX: 0, // 元素拖拽前距离浏览器的X轴位置
      startclientY: 0, //元素拖拽前距离浏览器的Y轴位置
      elLeft: 0, // 元素的左偏移量
      elTop: 0, // 元素的右偏移量
      clone: null,//复制的元素


      list: []
    };
  },
  methods: {
    // 页面初始化
    initBodySize() {
      this.initWidth = this.$refs.back_box.clientWidth; // 拿到父元素宽 背景盒子的宽高
      this.initHeight = this.$refs.back_box.clientHeight;
      this.bodyWidth = document.body.clientWidth // 浏览器的宽高
      this.bodyHeight = document.body.clientHeight
    },
    handler_dragstart(event) {
      console.log('拖拽开始', event.target.id, event);
      // 设置数据
      event.dataTransfer.setData('text/plain', event.target.id);
      // 设置拖动效果 设置既复制又移动
      event.effectAllowed = 'copyMove';
      this.startclientX = event.clientX; // 记录拖拽元素初始位置  要处理一下
      this.startclientY = event.clientY;
      const target = event.target.cloneNode(true); // 复制拖拽的元素
      this.clone = target; // 保存复制的元素
    },
    dragend(event) {
      //计算偏移量
      console.log(event, "结束位置")
      let x = event.clientX - this.startclientX; // 计算偏移量
      let y = event.clientY - this.startclientY;
      const box = this.$refs.back_box; // 获取盒子元素
      const rect = box.getBoundingClientRect(); // 获取盒子的位置信息


      console.log('左边界位置:', rect.left);
      // console.log('右边界位置:', rect.right);
      console.log('顶部位置:', rect.top);
      // console.log('底部位置:', rect.bottom);
      let top = y - rect.top
      let left = x
      let eltop = Number(top / this.initHeight * 100).toFixed(2)
      let elleft = Number(left / this.initWidth * 100).toFixed(2)
      this.list.push({
        left: elleft,
        top: eltop
      })
      console.log(this.list)
      event.dataTransfer.clearData();
    },
    //已有的数据拖动
    dragstart(e, item) {
      console.log(e, item, "子元素开始拖拽")
      this.startclientX_c = e.clientX; // 记录拖拽元素初始位置
      this.startclientY_c = e.clientY;
    },
    dragend_handler(e, item) {
      console.log(e, item, "子元素结束拖拽")
      console.log(item)


      let x = e.clientX - this.startclientX_c; // 计算偏移量
      let y = e.clientY - this.startclientY_c;
      let top = 0, left = 0;
      top += y
      left += x
      console.log(top, left, this.initHeight, this.initWidth)


      let eltop = Number(top / this.initHeight * 100).toFixed(2)
      let elleft = Number(left / this.initWidth * 100).toFixed(2)
      console.log(eltop, elleft)
      console.log(Number(item.top) + Number(eltop), Number(item.left) + Number(elleft))
      item.top = Number(item.top) + Number(eltop)
      item.left = Number(item.left) + Number(elleft)
      // let left += y
      // item.top += x;
      // item.left +=y
      console.log(item)


    },
    // 当被拖动元素在目标元素内时触发
    hander_dragover(event) {
      // console.log(event)
      // event.target.style.background = 'lightblue';
      event.preventDefault();
    },
    handler_drop(event) {
      event.preventDefault();
    },
    handler_dragLeave(event) {
      event.target.style.background = 'white';
      event.preventDefault();
    },




  },
  mounted() {
    this.initBodySize()
  },
};
</script>


<style scoped>
#copy,
#move {
  border: 1px solid #000;
  width: 100px;
  height: 100px;
}
#copyTarget,
#moveTarget {
  width: 50vw;
  height: 50vh;
  border: 1px solid #ff0000;
  position: relative;
}
/* #newId {
  width: 200px;
  height: 50px;
  border: 1px solid darkcyan;
} */
#targtBoxicon {
  height: 20%;
  width: 8%;
  border: 1px solid darkcyan;
}
.targtBoxicon {
  width: 100px;
  height: 100px;
  border: 1px solid darkcyan;
  position: absolute;
}
</style>
```