JavaScript如何通过单击和拖动动态移动Div

Sto*_*der 26 html javascript onmousedown

好吧,它看起来应该很简单.我需要取一个已经存在的div并根据窗口内的鼠标位置移动它.我到处搜索过,它让我采用过于复杂的方式做同样的事情,并涉及使用j-query.我需要严格使用javascript来实现我的目标.

方法 :

var mousePosition;
var div;

(function createDiv(){

    div = document.createElement("div");
    div.style.position = "absolute";
    div.style.left = "0px";
    div.style.top = "0px";
    div.style.width = "100px";
    div.style.height = "100px";
    div.style.background = "red";
    div.style.color = "blue";

    div.addEventListener('mousedown', handleKeyPressed, true);

    document.body.appendChild(div);


})();

function handleKeyPressed(event) {

    event.preventDefault();

    mousePosition = {

        x : event.clientX,
        y : event.clientY

    };

    div.style.left = mousePosition.x;
    div.style.top = mousePosition.y;

    //alert("whoa!");

}
Run Code Online (Sandbox Code Playgroud)

ade*_*neo 46

我想你正在寻找更像这样的东西

var mousePosition;
var offset = [0,0];
var div;
var isDown = false;

div = document.createElement("div");
div.style.position = "absolute";
div.style.left = "0px";
div.style.top = "0px";
div.style.width = "100px";
div.style.height = "100px";
div.style.background = "red";
div.style.color = "blue";

document.body.appendChild(div);

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

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

document.addEventListener('mousemove', function(event) {
    event.preventDefault();
    if (isDown) {
        mousePosition = {

            x : event.clientX,
            y : event.clientY

        };
        div.style.left = (mousePosition.x + offset[0]) + 'px';
        div.style.top  = (mousePosition.y + offset[1]) + 'px';
    }
}, true);
Run Code Online (Sandbox Code Playgroud)

小提琴

  • @StoneAgeCoder - 是的,需要简单的 JS 单元。让我们看看是否无法修复抖动,一秒钟。 (2认同)
  • 这是迄今为止我所见过的最好的解决方案。该脚本很小,易于理解,其结果比我在各种浏览器上看到的其他任何工具都要好。我不得不发表评论并投票,即使将来再次发现它。 (2认同)

mma*_*mma 10

支持触摸输入

所有其他答案(包括接受的答案)都不适用于触摸输入。触摸输入的事件与鼠标输入的事件不同。请参阅在 MDN 上使用触摸事件

以下代码片段甚至适用于触摸输入。我已经突出显示了需要添加以支持触摸设备的所有代码行。
这里的基本思想是包含draggable在类列表中的每个元素都应该是可拖动的。当您有大量需要拖动的元素时,这个概念更容易理解。

有关演示,请参阅故障页面和以下内容。

const d = document.getElementsByClassName("draggable");

for (let i = 0; i < d.length; i++) {
  d[i].style.position = "relative";
}

function filter(e) {
  let target = e.target;

  if (!target.classList.contains("draggable")) {
    return;
  }

  target.moving = true;
  
//NOTICE THIS 
  e.clientX ? // Check if Mouse events exist on user' device
  (target.oldX = e.clientX, // If they exist then use Mouse input
  target.oldY = e.clientY) :
  (target.oldX = e.touches[0].clientX, // otherwise use touch input
  target.oldY = e.touches[0].clientY)
//NOTICE THIS  Since there can be multiple touches, you need to mention which touch to look for, we are using the first touch only in this case

  target.oldLeft = window.getComputedStyle(target).getPropertyValue('left').split('px')[0] * 1;
  target.oldTop = window.getComputedStyle(target).getPropertyValue('top').split('px')[0] * 1;

  document.onmousemove = dr;
//NOTICE THIS 
  document.ontouchmove = dr;
//NOTICE THIS 

  function dr(event) {
    event.preventDefault();

    if (!target.moving) {
      return;
    }
//NOTICE THIS 
    event.clientX ?
    (target.distX = event.clientX - target.oldX,
    target.distY = event.clientY - target.oldY) :
    (target.distX = event.touches[0].clientX - target.oldX,
    target.distY = event.touches[0].clientY - target.oldY)
//NOTICE THIS 

    target.style.left = target.oldLeft + target.distX + "px";
    target.style.top = target.oldTop + target.distY + "px";
  }

  function endDrag() {
    target.moving = false;
  }
  target.onmouseup = endDrag;
//NOTICE THIS 
  target.ontouchend = endDrag;
//NOTICE THIS 
}
document.onmousedown = filter;
//NOTICE THIS 
document.ontouchstart = filter;
//NOTICE THIS 
Run Code Online (Sandbox Code Playgroud)
.draggable {
  width: 100px;
  height: 100px;
  background: red;
}
Run Code Online (Sandbox Code Playgroud)
<div class="draggable"></div>
Run Code Online (Sandbox Code Playgroud)


jhy*_*yap 6

检查这是否比adeneo更平滑:FIDDLE

var m = document.getElementById('move');
m.addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);

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

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

function move(e) {
    m.style.top = e.clientY + 'px';
    m.style.left = e.clientX + 'px';
};
Run Code Online (Sandbox Code Playgroud)


min*_*vip 5

我只是对@adeneo 非常有效的答案做了一个小改动。如果所有内容都包含在一个函数中,并且每个事件都附加到 div,则您可以将其用作库的一部分。

调用以下函数并传递一个 id。如果 div 不存在,则创建它。

function drag_div(div_id){
var div;

div = document.getElementById(div_id);

if(div == null){
   div = document.createElement("div");
   div.id = div_id;
   div.style.position = "absolute";
   div.style.left = "0px";
   div.style.top = "0px";
   div.style.width = "100px";
   div.style.height = "100px";
   div.style.background = "red";
   div.style.color = "blue";
   document.body.appendChild(div);
}

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

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

div.addEventListener('mousemove', function(event) {
    event.preventDefault();
    if (div.isDown) {
        div.mousePosition = {

            x : event.clientX,
            y : event.clientY

        };
        div.style.left = (div.mousePosition.x + div.offset[0]) + 'px';
        div.style.top  = (div.mousePosition.y + div.offset[1]) + 'px';
    }
}, true);
}
Run Code Online (Sandbox Code Playgroud)