Javascript 简单的拖放代码

Javascript 简单的拖放代码,javascript,drag-and-drop,draggable,drag,Javascript,Drag And Drop,Draggable,Drag,我正在努力完成一个看似简单的javascript练习,编写一个普通的拖放操作。我认为我的“addeventlisteners”犯了一个错误,下面是代码: var ele = document.getElementsByClassName ("target")[0]; var stateMouseDown = false; //ele.onmousedown = eleMouseDown; ele.addEventListener ("onmousedown" , eleMouseDown , f

我正在努力完成一个看似简单的javascript练习,编写一个普通的拖放操作。我认为我的“addeventlisteners”犯了一个错误,下面是代码:

var ele = document.getElementsByClassName ("target")[0];
var stateMouseDown = false;
//ele.onmousedown = eleMouseDown;
ele.addEventListener ("onmousedown" , eleMouseDown , false);

function eleMouseDown () {
    stateMouseDown = true;
    document.addEventListener ("onmousemove" , eleMouseMove , false);
}

function eleMouseMove (ev) {
    do {
        var pX = ev.pageX;
        var pY = ev.pageY;
        ele.style.left = pX + "px";
        ele.style.top = pY + "px";
        document.addEventListener ("onmouseup" , eleMouseUp , false);
    } while (stateMouseDown === true);
}

function eleMouseUp () {
    stateMouseDown = false;
    document.removeEventListener ("onmousemove" , eleMouseMove , false);
    document.removeEventListener ("onmouseup" , eleMouseUp , false);
}

下面是一个JSFIDLE,它可以工作:

有两个主要问题,第一个是使用
onmousedown
onmousemove
onmouseup
。我相信这些仅用于附带的活动:

document.body.attachEvent('onmousemove',drag);
mousedown
mousemove
mouseup
则用于事件侦听器:

document.body.addEventListener('mousemove',drag);
第二个问题是move事件函数中的do-while循环。每次鼠标移动像素时都会调用该函数,因此不需要循环:

var ele = document.getElementsByClassName ("target")[0];
ele.addEventListener ("mousedown" , eleMouseDown , false);

function eleMouseDown () {
    stateMouseDown = true;
    document.addEventListener ("mousemove" , eleMouseMove , false);
}

function eleMouseMove (ev) {
    var pX = ev.pageX;
    var pY = ev.pageY;
    ele.style.left = pX + "px";
    ele.style.top = pY + "px";
    document.addEventListener ("mouseup" , eleMouseUp , false);
}

function eleMouseUp () {
    document.removeEventListener ("mousemove" , eleMouseMove , false);
    document.removeEventListener ("mouseup" , eleMouseUp , false);
}

顺便说一下,我必须使目标的位置绝对,它才能工作。

你也可以试试这把小提琴


蒂图洛·德米帕吉纳
#目标{
宽度:100px;
高度:100px;
背景色:#ffc;
边框:2件纯蓝;
位置:绝对位置;
}
window.onload=函数(){
var el=document.getElementById('target');
var-mover=false,x,y,posx,posy,first=true;
el.onmousedown=函数(){
mover=true;
};
el.onmouseup=函数(){
mover=false;
第一个=正确;
};
el.onmousemove=功能(e){
如果(移动器){
如果(第一){
x=e.offsetX;
y=e.offsetY;
第一个=假;
}
posx=e.pageX-x;
posy=e.pageY-y;
this.style.left=posx+'px';
this.style.top=posy+'px';
}
};
}

我刚刚做了一个简单的拖动

这是一种单行程序用法,它可以处理诸如鼠标到元素左上角的偏移、onDrag/onStop回调以及SVG元素拖动等问题

这是代码

// simple drag
function sdrag(onDrag, onStop) {
    var startX = 0;
    var startY = 0;
    var el = this;
    var dragging = false;

    function move(e) {
        el.style.left = (e.pageX - startX ) + 'px';
        el.style.top = (e.pageY - startY ) + 'px';
        onDrag && onDrag(el, e.pageX, startX, e.pageY, startY);
    }

    function startDragging(e) {
        if (e.currentTarget instanceof HTMLElement || e.currentTarget instanceof SVGElement) {
            dragging = true;
            var left = el.style.left ? parseInt(el.style.left) : 0;
            var top = el.style.top ? parseInt(el.style.top) : 0;
            startX = e.pageX - left;
            startY = e.pageY - top;
            window.addEventListener('mousemove', move);
        }
        else {
            throw new Error("Your target must be an html element");
        }
    }

    this.addEventListener('mousedown', startDragging);
    window.addEventListener('mouseup', function (e) {
        if (true === dragging) {
            dragging = false;
            window.removeEventListener('mousemove', move);
            onStop && onStop(el, e.pageX, startX, e.pageY, startY);
        }
    });
}

Element.prototype.sdrag = sdrag;
使用它:

document.getElementById('my_target').sdrag();
您还可以使用onDrag和onStop回调:

document.getElementById('my_target').sdrag(onDrag, onStop);
有关更多详细信息,请查看我的回购协议: 我就是这样做的

var MOVE={
startX:未定义,
斯塔蒂:未定义,
项目:空
};
函数contentDiv(颜色、宽度、高度){
var result=document.createElement('div');
result.style.width=宽度+px;
result.style.height=高度+px;
result.style.backgroundColor=颜色;
返回结果;
}
功能(内容){
var outer=document.createElement('div');
var internal=document.createElement('div');
outer.style.position='relative';
internal.style.position='relative';
internal.style.cursor='move';
inner.style.zIndex=1000;
外部。子对象(内部);
内附子项(内容);
内部.addEventListener('mousedown',函数(evt){
MOVE.item=this;
MOVE.startX=evt.pageX;
MOVE.startY=evt.pageY;
})
返回外部;
}
函数bodyOnload(){
document.getElementById('td1').appendChild(可移动(contentDiv('blue',100100));
document.getElementById('td2').appendChild(可移动(contentDiv('red',100100));
document.addEventListener('mousemove',函数(evt){
如果(!MOVE.item)返回;
if(evt.which!==1){return;}
var dx=evt.pageX-MOVE.startX;
var dy=evt.pageY-MOVE.startY;
MOVE.item.parentElement.style.left=dx+'px';
MOVE.item.parentElement.style.top=dy+'px';
});
document.addEventListener('mouseup',函数(evt){
如果(!MOVE.item)返回;
var dx=evt.pageX-MOVE.startX;
var dy=evt.pageY-MOVE.startY;
var sty=MOVE.item.style;
sty.left=(parseFloat(sty.left)| | 0)+dx+‘px’;
sty.top=(parseFloat(sty.top)| | 0)+dy+'px';
MOVE.item.parentElement.style.left='';
MOVE.item.parentElement.style.top='';
MOVE.item=null;
MOVE.startX=未定义;
MOVE.startY=未定义;
});
}
bodyOnload()
表格{
用户选择:无
}


感谢您的详细回复。当mousedown处于活动状态时,我正在为mousemove使用Do While,否则它不应该运行。。。如果我启用Do While循环,Firefox会停止。@Kayote我得到了答案,但由于
mousemove
事件调用
eleMouseMove()
的频率,我会根据需要对其进行一点更新。这是很久以前的事了,但值得注意的是(正如上一条评论中的代码所示),mouseup的事件监听器应该添加到eleMouseDown函数中,而不是eleMouseMove中;后者被称为很多,您不希望每次用户移动鼠标时都添加mouseup侦听器。避免初始鼠标移动时跳转的版本:为什么使用offsetX/Y?来停止可拖动的鼠标指针跳转。我明白了。当然你应该使用CSS类而不是内联样式。把它看得又快又脏。
document.getElementById('my_target').sdrag(onDrag, onStop);