JS+Vue实现元素拖拽

背景

工作中遇到这样的一个需求:将页面侧边菜单拖拽到页面中间的画布中,然后在画布内可对此菜单进行随意移动。操作如下图所示:


代码查看地址

功能分析

页面分为菜单和画布两个部分,其中菜单部分为拖拽元素,画布部分为放置元素。
整个操作也分为两个部分,首先从侧边栏拖拽到画布中央,放置在画布上后,再次点击画布中的元素可对其进行拖拽移动。

功能实现

第一步:从侧边拖拽到画布上

引入vuedraggableSortableJS

<div class="main">
    <draggable group="components" draggable=".draggable" @add="onAdd"></draggable>
</div>

//  draggable 指定元素内的哪些项目应可拖动
//  sort 列表内排序
//  group 要将元素从一个列表拖到另一个列表中,两个列表必须具有相同的组名
<div class="aside">
    <draggable class="draggable-tab" draggable=".panel-item"
           group="components" :sort="false" @end="onEnd">
        ....
</draggable>

import draggable from 'vuedraggable'

export default {
  methods: {
    onAdd (evt) { // 元素从另一个列表拖放到列表中
       console.log(evt)
    },
    onEnd (evt) { // 元素拖动结束
      if (evt.pullMode) {
         console.log(evt)
      }
    }
  }
}

第二步:拖拽移动画布中的元素位置

被移动元素需设置为绝对定位,其父元素设置为相对定位

<div class="aside">侧边菜单栏</div>
<div class="container">
    <div class="panel-item" id="panel">
        <div class="move" @mousedown="mousedown"></div>
    </div>
</div>

<style>
.container {
    position: relative;
}

.panel-item {
    position: absolute;
}
</style>
import $ from 'jquery'

export default {
  methods: {
    mousedown (evt) {
      $('#panel').css('z-index', ++this.zIndex)
      const offsetX = evt.offsetX
      // 限制拖拽范围,不超过当前可视窗口
      const drag = (evt) => {
        let xScale
        if (this.position === 'right') {
          xScale = evt.x < (document.body.clientWidth - $('.aside').width() - 10) &&
            evt.x > 10
        } else {
          xScale = evt.x < (document.body.clientWidth - 50) &&
            evt.x > $('.aside').width()
        }
        if (xScale) {
          if (this.position === 'right') {
            const left = (evt.x - offsetX)
            $('#panel').css('left', left)
          } else {
            if ($('.aside').width() > 0) {
              $('#panel').css('left', evt.x - offsetX - 180)
            } else {
              $('#panel').css('left', evt.x - 120)
            }
          }
        }
        const yScale = evt.y > 10 && evt.y < (document.body.clientHeight - 10)
        if (yScale) {
          $('#panel').css('top', evt.y - 5)
        }
      }
      this.onDrag(drag)
    },
    onDrag (drag) {
      const up = () => {
        document.removeEventListener('mousemove', drag)
        document.removeEventListener('mouseup', up)
      }
        // 监听鼠标移动事件,移动过程中不断改变被拖拽元素的位移
      document.addEventListener('mousemove', drag)
      // 监听鼠标松开事件,当鼠标松开时,取消元素位移改变
      document.addEventListener('mouseup', up)
    },
  }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容