当鼠标已经位于元素上并且已经移动时,如何启用可拖动?

时间:2018-11-25 20:28:48

标签: javascript html draggable

我编写了代码,以允许在鼠标向下滑动HTML元素一定时间后再拖动该元素。

问题是,当我使用本机HTML拖放功能时,如果超时(鼠标在该元素上一直按下该时间段),则启用draggable属性。在超时之前,鼠标在其处于按下状态时被移动,HTML不会触发dragstart事件,甚至不会开始拖动该元素。

下面有一个例子。

var t;

function startDelayedDrag() {
  clearTimeout(t);
  document.getElementById('dragtarget').draggable = false;
  console.log('mousedown')
  t = setTimeout(function() {
    console.log('dragging enabled')
    document.getElementById('dragtarget').draggable = true;
  }, 1000);
}
.droptarget {
  float: left;
  width: 100px;
  height: 35px;
  margin: 15px;
  padding: 10px;
  border: 1px solid #aaaaaa;
  user-select: none;
}
<div class="droptarget">
  <p onmousedown="startDelayedDrag()" id="dragtarget">Drag me!</p>
</div>

<div class="droptarget"></div>

1 个答案:

答案 0 :(得分:3)

这是一个棘手的问题,可能与您的想法有所不同,但是这里有一个解决问题的方法:

  1. 开始拖动事件
  2. 通过使用$ echo ./run.sh a "b c" ./run.sh a b c $ echo './run.sh a "b c"' ./run.sh a "b c" $ echo "./run.sh a \"b c\"" ./run.sh a "b c" $ echo "./run.sh a 'b c'" ./run.sh a 'b c' $ echo ./run.sh a b\\ c ./run.sh a b\ c 设置图像来隐藏拖动对象
  3. 克隆拖动元素节点,隐藏该克隆并将其添加到文档中(因为不可能更改setDragImage设置的图像)
  4. 开始超时以更改幽灵元素的可见性

这可以通过许多方式加以改进,但是我认为您可以了解其工作原理。作为参考,请参见以下代码段:

setDragImage
const [$drag] = document.getElementsByClassName('drag')
const [$pixel] = document.getElementsByClassName('pixel')
let $ghost = null

$drag.addEventListener("dragstart", e => {
  // set the current draged element invisible
  e.dataTransfer.setDragImage($pixel, 0, 0)
  
  // create a ghost element
  $ghost = $drag.cloneNode(true)
  $ghost.style.position = "absolute"
  $ghost.style.display = "none"
  document.body.appendChild($ghost)

  setTimeout(() => {
    $ghost.style.display = 'block'
  }, 1000)
})

$drag.addEventListener("drag", e => {
  // keep the ghost position to follow the mouse while dragging 
  $ghost.style.left = `${e.clientX}px`
  $ghost.style.top = `${e.clientY}px`
}, false);

$drag.addEventListener("dragend", e => {
  // remove the ghost
  if ($ghost.parentNode) $ghost.parentNode.removeChild($ghost)
}, false)
.content {
  display: flex;
}

.box {
  width: 100px;
  height: 35px;
  padding: 10px;
  margin: 10px;
  border: 1px solid #aaaaaa;
}

.drop {
  user-select: none;
}

.drag {
  text-align: center;
}

.pixel {
  width: 1px;
  height: 1px;
  background-color: white;
}