纯javascript draggable元素 [英] pure javascript draggable element

查看:77
本文介绍了纯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);

函数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';

to:

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

元素只有在向正x轴方向拖动时才会被正确拖动(向右并且朝向正y轴(到底部)并且当触发mouseup时它将被定位在最左边最顶角区域附近的某处(大约0,0)

解决方案

非常有趣,到目前为止只用jQuery完成了它。重写了一下,并确保每个鼠标移动之后都删除了事件监听器 - 这将是一个内存泄漏,你可能会开始注意到:



http://jsfiddle.net/8wtq17L8/

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

contextmenu.addEventListener('mousedown',函数(事件){

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);

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

似乎运作良好。 : - )



++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++ b $ b

编辑 - 我想我也会添加一个带触摸支持的版本(虽然新设备似乎模仿鼠标事件)。不像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);

函数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';
}


I know there're example of doing this on the web but every example is different and so is my own implementation. I'm trying to figure what's wrong with my implementation since it doesn't work as expected.

code snippet:

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/

can't really figure out what's wrong but I've noticed that if I change the following lines:

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

to :

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

The element will be properly dragged only when it's being dragged towards the positive x-axis (to the right) and towards the positive y-axis (to the bottom) and when mouseup is triggered it'll be positioned in somewhere near the left-most top-most corner area (around 0,0)

解决方案

Quite interesting, had so far only done it with jQuery. Rewrote it a bit and made sure that every mousemove has it's event listener removed afterwards - that would be a memory leak that you might start to notice otherwise :

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';
}

Seems to be working well. :-)

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

Edit - thought I'd add a version with touch support too (although newer devices seem to emulate mouse events). Not like Jquery where you can select multiple event listeners so it's mostly a repetition, just with touch events :

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 draggable元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆