javascript 使用拖动来移动元素

javascript use drag to move element

如何设置元素的位置?当用户拖动一个元素(图像)时,我想让它同步移动。我看到正在调用我的 "mousemove" 处理程序。但是我无法让元素实际移动。

这是 mousemove 处理程序(被拖动的元素是 "overlay"):

function handleMouseMove (event)
{
  var deltaX = event.movementX;
  var deltaY = event.movementY;

  var divOverlay = document.getElementById ("overlay");
  var rect = divOverlay.getBoundingClientRect();

  divOverlay.style.left = rect.x + deltaX;
  divOverlay.style.top = rect.y + deltaY;
}

这是 "overlay" 的 html:

<div id="overlay">
  ... some other stuff ...
  <img id="large" src="something.jpg" >
</div>

和 css:

#overlay {position:absolute; left:0; top:0}

似乎显示了默认的拖动操作,它是 "overlay" 随鼠标移动的影子。但是元素本身并没有移动。

jQuery 适合您吗?由于代码已经存在,它使您正在做的事情变得非常简单。

http://jqueryui.com/demos/draggable/

演示:http://jsfiddle.net/wfbY8/4/

JavaScript代码

window.onload = addListeners;

function addListeners(){
    document.getElementById('dxy').addEventListener('mousedown', mouseDown, false);
    window.addEventListener('mouseup', mouseUp, false);

}

function mouseUp()
{
    window.removeEventListener('mousemove', divMove, true);
}

function mouseDown(e){
  window.addEventListener('mousemove', divMove, true);
}

function divMove(e){
    var div = document.getElementById('dxy');
  div.style.position = 'absolute';
  div.style.top = e.clientY + 'px';
  div.style.left = e.clientX + 'px';
}​

不确定您的实际实施情况。但是这段代码有效:

要使用您的代码来完成,这里是代码。您的代码的一个明显问题是您需要将 'px' 添加到 style.left 和 style.right。此外,您实际上如何处理代码中的事件也是未知的。使用这段代码,元素在一个圆圈中移动,你需要修复它,但你明白了。

var divOverlay = document.getElementById ("overlay");
var isDown = false;
divOverlay.addEventListener('mousedown', function(e) {
    isDown = true;
}, true);

document.addEventListener('mouseup', function() {
  isDown = false;
}, true);

document.addEventListener('mousemove', function(event) {
   event.preventDefault();
   if (isDown) {
   var deltaX = event.movementX;
   var deltaY = event.movementY;
  var rect = divOverlay.getBoundingClientRect();
  divOverlay.style.left = rect.x + deltaX + 'px';
  divOverlay.style.top  = rect.x + deltaX + 'px';
 }
}, true);

下面是另一种方法。 Codepen example

var offset = [0,0];
var divOverlay = document.getElementById ("overlay");
var isDown = false;

divOverlay.addEventListener('mousedown', function(e) {
isDown = true;
offset = [
    divOverlay.offsetLeft - e.clientX,
    divOverlay.offsetTop - e.clientY
 ];
}, true);

document.addEventListener('mouseup', function() {
   isDown = false;
}, true);

document.addEventListener('mousemove', function(e) {
    event.preventDefault();
    if (isDown) {
        divOverlay.style.left = (e.clientX + offset[0]) + 'px';
        divOverlay.style.top  = (e.clientY + offset[1]) + 'px';
   }
}, true);

几周前我确实为 Angular、see here 做了类似的东西。它可能会对你有所帮助。

基本上,我想做一些您可能正在考虑做的事情,但是要使用拖动事件,您还需要放下正在拖动的元素(至少这是我最终搜索的结果)。因此,如果您只想 drag/move 元素,您需要能够使用 topbottomleftright 样式设置它们在页面上的位置.因此,理想情况下,这些元素必须具有 fixedabsolute 的位置。

然后你进入这个的核心,即计算你要用来移动元素的向量。因为 mousemove 事件只派发 MouseEvent,它可以让你访问鼠标坐标,你可以计算你的鼠标在哪个向量中移动,并通过相同的向量移动元素。

基本上我所做的是(希望它在 ES5 中是可以理解的):

var elementPosition = [0,0];
var mousePosition   = [0,0];
var element         = document.getElementById('yourElement');

var mainEH = function (event) {
    mousePosition = [event.clientX, event.clientY];
    document.addEventListener('mousemove', calcEH);
    document.addEventListener('mouseup', removeHandlers);
    document.addEventListener('contextmenu', removeHandlers);
};

var calcEH = function (event) {
    var vector      = [-mousePosition[0] + event.clientX, -mousePosition[1] + event.clientY];
    mousePosition   = [mousePosition[0] + vector[0], mousePosition[1] + vector[1]];
    elementPosition = [elementPosition[0] + vector[0], elementPosition[1] + vector[1]];
    updatePosition();
};

var removeHandlers = function () {
    document.removeEventListener('mousemove', calcEH);
    document.removeEventListener('mouseup', removeHandlers);
    document.removeEventListener('contextmenu', removeHandlers);
};

function updatePosition() {
    element.style.left = elementPosition[0] + "px";
    element.style.top  = elementPosition[1] + "px";
}

element.addEventListener('mousedown', mainEH, true);

我不确定这段代码是否有效,因为我现在无法对其进行测试,但您可以看到 here 我是如何使用 angular 完成此操作的。希望它对你有用。至少你明白了。无论如何,您可能需要 运行 一些为您设置元素初始位置的函数。

更新

我刚刚意识到这不是您要找的东西。如果我理解正确的话,你想在拖放时移动整个元素。但是我可能会在这里留下答案,因为解决方案可能非常相似。我可能会使用我之前发布的逻辑来做到这一点,并且为了真正能够移动元素,我会在触发 mousemove 事件时将它的位置设置为绝对位置,然后在 mouseup 上你可以删除位置绝对属性。