0

I'm extremely frustrated with this problem I'm having. I've put together a click/drag code, where when you click on a certain DOM element, it drags the specified DOM element on mouse move, then releases the elements on mouse up.

The problem I'm running into is that I'm trying to remove the event listener on the mouse up, thus the DOM elements stop moving on the mouse event. But nothing seems to work to remove the event.

Here's the code.

var cls_MouseDrag = (function(){

    var obj_Element, obj_Drag, v_yPos, v_xPos = null;

    function Constructor(par_ElementId, par_ElementDrag){
        obj_Element = document.getElementById(par_ElementId);
        obj_Drag = document.getElementById(par_ElementDrag);
        obj_Element.addEventListener('mousedown', MouseDown, false);
    };

    function MouseDown(){
        var v_offset = obj_Element.getBoundingClientRect();
        v_xPos = event.clientX - v_offset.left;
        v_yPos = event.clientY - v_offset.top;
        document.addEventListener('mousemove', cls_MouseDrag.MouseMove);
    };

    function MouseUp(){
        document.removeEventListener('mousemove', cls_MouseDrag.MouseMove);
    };

    function MouseMove(){
        event.preventDefault();
        obj_Drag.style.top = event.clientY - v_yPos + 'px';
        obj_Drag.style.left = event.clientX - v_xPos + 'px';
    };

    return { 
        Constructor:Constructor,
        MouseMove:MouseMove
    };

})();

cls_MouseDrag.Constructor('file_drag','my_file');

Updated code

var cls_MouseDrag = (function(){

    var v_ClickElement = null, v_DragElement = null, v_yPos = null, v_xPos = null;

    function Constructor(par_ClickElementId, par_DragElementId){
        document.getElementById(par_ClickElementId).addEventListener('mousedown', function () { MouseDown(par_ClickElementId, par_DragElementId) }, false);
    }

    function MouseDown(par_ClickElementId, par_DragElementId){

        v_ClickElement = document.getElementById(par_ClickElementId);
        v_DragElement = document.getElementById(par_DragElementId);

        var v_offset = v_ClickElement.getBoundingClientRect();
        v_xPos = event.clientX - v_offset.left;
        v_yPos = event.clientY - v_offset.top;

        document.addEventListener('mouseup', MouseUp, false);
        document.addEventListener('mousemove', MouseMove, false);
    }

    function MouseUp(){
        document.removeEventListener('mouseup', MouseUp, false);
        document.removeEventListener('mousemove', MouseMove, false);
        var v_ClickElement = null, v_DragElement = null, v_yPos = null, v_xPos = null;
    }


    function MouseMove(){
        event.preventDefault();
        v_DragElement.style.top = event.clientY - v_yPos + 'px';
        v_DragElement.style.left = event.clientX - v_xPos + 'px';
    }

    return { 
        Constructor:Constructor,
    };

})();

cls_MouseDrag.Constructor('file_drag','my_file');

};
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mike Reed
  • 74
  • 7

2 Answers2

0

In Constructor, after this line:

obj_Element.addEventListener('mousedown', MouseDown, false);

you probably want

obj_Element.addEventListener('mouseup', MouseUp, false);

...otherwise, I don't see how MouseUp would be called.


Side note: The cls_MouseDrag. part of these lines:

document.addEventListener('mousemove', cls_MouseDrag.MouseMove);

...is unnecessary (but harmless). Instead:

document.addEventListener('mousemove', MouseMove);

Side note 2: You might also want to be consistent about whether you use the third argument (some older browsers still require it, so I would).

Side note 3: You don't put ; at the end of function declarations; it's a statement terminator, and declarations aren't statements.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Ah, that worked. Dumb mistake. It was a long night last night and I was tired. – Mike Reed Feb 04 '15 at 17:43
  • The code is a bit surprising: You're starting the drag on mousedown within one element, but then when the mouse moves, you're moving a *different* element. In that case (and perhaps just on general principal), you probably want to set the `mouseup` handler on `document` rather than the element you're not dragging. – T.J. Crowder Feb 04 '15 at 18:38
  • The mouse down is for a
    within a container
    . The inside div is positioned at the top of the container div, with other content within the container. That top area is where you have to click to drag the entire container. Good idea though.
    – Mike Reed Feb 04 '15 at 19:13
0

To remove a listener you have to have the matching add remove example:

function handler() {}
document.addEventListener('mousedown', handler);//to add
document.removeEventListener('mousedown', handler);//to remove

Conclusion the parameters passed to addEventListener should be the same as the ones passed to removeEventListener - otherwise it will not work.

Hope that helps.

I later have seen that you reedited, but I see no problem in your code now. Check: http://jsfiddle.net/atrifan/8o1gxpyw/ (console)

atrifan
  • 172
  • 5