vue 拖拽元素 固定在指定位置

如图,已实现拖拽效果,怎么能在鼠标拖动元素接近下划线时,被拖拽的元素能固定在绿色方框内

因为要适应不同的屏幕,以1280*720计算出来屏幕缩放比,所以左右或是上下会有一定的距离,

1649905338531.jpg
1649905386216.jpg

数据
let optionList: [
    {
        "type": "text",
        "student_answer": "桃之夭"
    },
    {
        "type": "blank",
        "left": 268.5625,
        "right": 418.5625,
        "top": 49,
        "bottom": 66,
        "answer": "灼灼其华"
    },
    {
        "type": "text",
        "student_answer": "去年今日"
    },
    {
        "type": "blank",
        "left": 494.5625,
        "right": 644.5625,
        "top": 49,
        "bottom": 66,
        "answer": "人面桃花"
    }
],
let option: [
 {
        "id": 0,
        "name": "灼灼其华",
        "left": 210,
        "right": 222,
        "top": 394,
        "bottom": 460
    },
    {
        "id": 1,
        "name": "人面桃花",
        "left": 246,
        "right": 456,
        "top": 394,
        "bottom": 460
    },
]
结构
<div class="container"
      <div class="bankedContent">
            <!--内容及空格-->
            <span v-for="(item, index) in optionList" :key="index" class="text-wrapper">
                <template v-if="item.type === 'text'">{{item.student_answer}}</template>
                <template v-else>
                    <input
                       type="text"
                       :style="`width:${item.option.length * 120}px;`"
                       v-model.trim="item.student_answer"
                       :disabled="true"
                       class="blankInput"
                    />
                </template>
              </span>
          </div>
          <!--可被拖拽的元素-->
          <ul class="optionList">
              <li v-for="(item, index) in option"
                  :key="'drag'+index"
                  ref="element"
                  class="oneOption"
                  v-drag
                  :style="bottomStyle"
                  draggable="false">
                  <p>{{item.name}}</p>
              </li>
          </ul>
</div>
拖拽指令
directives: {
    drag: { // 拖拽指令
      inserted: function (el) {
        el.onmousedown = function (ev) {
          el.setAttribute('data-flag', false)
           // 用元素距离视窗的X、Y坐标,减去el元素最近的相对定位父元素的left、top值
          var sX = ev.clientX - el.offsetLeft
          var sY = ev.clientY - el.offsetTop
          // 不断地更新元素的left、top值
          document.onmousemove = function (ev) {
            el.style.left = ev.clientX - sX + 'px'
            el.style.top = ev.clientY - sY + 'px'
          }
        
          document.onmouseup = function (event) {
            document.onmousemove = null
            document.onmouseup = null;
          }
        }
      }
    }
  }
阅读 6.4k
3 个回答
<div id="target" ondrop="ondropEvent(event)" ondragover="ondragoverEvent(event)"></div>

其实你要的是“吸附效果”,对吧?

你要明白,很多效果并不是只有一条路。比如,画一个矩形,你可以直接画出来,也可以先画一个大矩形,然后用背景色画另一个矩形,盖住它的一部分。

具体到你这个问题,你可以计算出一个范围值,当鼠标坐标在这个范围值内的时候,被拖动的元素就停留在绿色方框位置,只有超出的时候才继续跟着鼠标动。

有一个想法不知道可不可行:

  1. 绿色空格可以用div写,不用input写,里面套一个隐藏的元素
  2. 拖拽之后,监测鼠标操作和绿色空格距离,如果到绿色方框那里dragLeave,就显示(1)中隐藏的元素

好久没写vue,就不上demo了


如果考虑能够拖出的话,可以使用 drag & drop Api

参考这个问题:元素拖拽问题

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题