javascript - 纯javascript可拖动元素

标签 javascript draggable

我知道网上有这样做的例子,但每个例子都不一样,我自己的实现也不一样。我试图弄清楚我的实现有什么问题,因为它没有按预期工作。

代码片段:

var mousePressX = -1;
var mousePressY = -1;

document.getElementById("contextMenu").addEventListener("mousedown", function(event) {
    mousePressX = event.clientX;
    mousePressY = event.clientY;
}, false);

document.getElementById("contextMenu").addEventListener("mouseup", function(event) {
    mousePressX = -1;
    mousePressY = -1;
}, false);

document.getElementById("contextMenu").addEventListener("mousemove", function(event) {
    if (mousePressX != -1 && mousePressY != -1) {
        repositionElement(event.target, event.clientX, event.clientY);
    }
}, false);

function repositionElement(element, currentMouseX, currentMouseY) {
    element.style.left = element.offsetLeft + (currentMouseX - mousePressX) + 'px';
    element.style.top = element.offsetTop + (currentMouseY - mousePressY) + 'px';
}

jsfiddle : http://jsfiddle.net/4rLctko8/

无法真正找出问题所在,但我注意到如果我更改以下行:

element.style.left = element.offsetLeft + (currentMouseX - mousePressX) + 'px';
element.style.top = element.offsetTop + (currentMouseY - mousePressY) + 'px';

到:

element.style.left = currentMouseX - mousePressX + 'px';
element.style.top = currentMouseY - mousePressY + 'px';

只有当元素被拖向正 x 轴(向右)和正 y 轴(向底部)并且当 mouseup 被触发时,它才会被正确拖动,它会被定位在附近的某个地方最左边的最上 Angular 区域(0,0 左右)

最佳答案

非常有趣,到目前为止只用 jQuery 完成过。稍微重写它并确保每个 mousemove 之后都删除了它的事件监听器 - 这将是内存泄漏,否则您可能会开始注意到:

http://jsfiddle.net/8wtq17L8/

var contextmenu = document.getElementById('contextMenu');
var initX, initY, mousePressX, mousePressY;

contextmenu.addEventListener('mousedown', function(event) {

    initX = this.offsetLeft;
    initY = this.offsetTop;
    mousePressX = event.clientX;
    mousePressY = event.clientY;

    this.addEventListener('mousemove', repositionElement, false);

    window.addEventListener('mouseup', function() {
      contextmenu.removeEventListener('mousemove', repositionElement, false);
    }, false);

}, false);

function repositionElement(event) {
    this.style.left = initX + event.clientX - mousePressX + 'px';
    this.style.top = initY + event.clientY - mousePressY + 'px';
}

似乎运作良好。 :-)

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

编辑 - 我想我也会添加一个支持触摸的版本(尽管较新的设备似乎可以模拟鼠标事件)。不像 Jquery,你可以选择多个事件监听器,所以它主要是重复,只有触摸事件:

http://codepen.io/Shikkediel/pen/VLZKor?editors=011

var object = document.getElementById('element'),
initX, initY, firstX, firstY;

object.addEventListener('mousedown', function(e) {

    e.preventDefault();
    initX = this.offsetLeft;
    initY = this.offsetTop;
    firstX = e.pageX;
    firstY = e.pageY;

    this.addEventListener('mousemove', dragIt, false);

    window.addEventListener('mouseup', function() {
        object.removeEventListener('mousemove', dragIt, false);
    }, false);

}, false);

object.addEventListener('touchstart', function(e) {

    e.preventDefault();
    initX = this.offsetLeft;
    initY = this.offsetTop;
    var touch = e.touches;
    firstX = touch[0].pageX;
    firstY = touch[0].pageY;

    this.addEventListener('touchmove', swipeIt, false);

    window.addEventListener('touchend', function(e) {
        e.preventDefault();
        object.removeEventListener('touchmove', swipeIt, false);
    }, false);

}, false);

function dragIt(e) {
    this.style.left = initX+e.pageX-firstX + 'px';
    this.style.top = initY+e.pageY-firstY + 'px';
}

function swipeIt(e) {
    var contact = e.touches;
    this.style.left = initX+contact[0].pageX-firstX + 'px';
    this.style.top = initY+contact[0].pageY-firstY + 'px';
}

关于javascript - 纯javascript可拖动元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29703473/

相关文章:

JQuery 向各个方向拖动/滑动 div

javascript - 如果可拖动元素应用了转换,则 jquery 可拖动包含不起作用

angularjs - 在 Angular 中使用 cdkDropListData 时出错,无法绑定(bind)到 'cdkDropListData',因为它不是 'div' 的已知属性

javascript - jquery scrollTop 动画完成后滚动触发

javascript - 如何记录立即调用 + 匿名函数?

javascript - 使用 AngularJS 在 Bootstrap 单选按钮上设置事件类

jQuery 的 draggable() 函数不起作用

javascript - 这里需要一些 javascript 帮助(简单)

php - 游戏的分数基于客户端倒计时。如何防弹呢?

jquery - 模拟这个效果,jquery draggable