3

I have some line of codes which will move an element to mouse position after it is mousedown-ed.

I want to remove the event attached to it, so it won't following the mouse position anymore after it is mouseup-ed!

The Problem

The element still follows the mouse after mouseup!

I want it to follow the mouse on mousedown and stop following the mouse after mouseup! How do I remove the mousemove listener from the element?

Here is the JS

jQuery(document).ready(function ($) {
    $(".crossY").on("mousedown", function (e) {
        var j = $(this);
        $(document).on("mousemove", function (e) {
            j.css({
                "top": e.pageY,
                "left": e.pageX
            });
        });
    })

    $(".crossY").on("mouseup", function (e) {
        var j = $(this);
        $(document).on("mousemove", function (e) {
            j.css({
                "top": j.css("top"),
                "left": j.css("left")
            });
        });
    });
});

and the FIDDLE DEMO

Strikeskids
  • 3,932
  • 13
  • 27
Ari
  • 4,643
  • 5
  • 36
  • 52
  • Although it may seem like the way to do this is to bind/unbind a handler, that takes a good bit more overhead than simply binding a single `mousemove` handler *outside* the `mousedown/up` events and having its behavior changed based on a shared variable. –  Jul 04 '15 at 14:17
  • ...like this: http://jsfiddle.net/v9d7ut5y/16/ I also put the `mouseup` on the `document` because it can be that the pointer isn't directly on the moved element when you mouseup. You can experiment both ways. –  Jul 04 '15 at 14:25

3 Answers3

3

In order to remove a mouse listener, you need to use the jQuery .off method. In order to get this to work easily, you should namespace the mousemove event. This will allow you to easily detach the necessary mousemove listener.

Inside the mousedown we want to attach the listener

$(document).on('mousemove.following', function (e) { /* my event handler */ })

Inside the mouseup we want to detach the listener

$(document).off('mousemove.following')

The following namespace makes sure that no other event listeners are detached.

Here is an example of this working (your jsfiddle except updated).

Another thing you might want to do is make the moving part centered underneath the mouse.

$(".crossY").on("mousedown", function (e) {
    var j = $(this);
    var height = j.height(), width = j.width();
    $(document).on("mousemove", function (e) {
        j.css({
            "top": e.pageY - height/2,
            "left": e.pageX - width/2,
        });
    });
})

Subtracting half of the element height and width keeps the element centered underneath the mouse, which will also ensure that the mouseup even is fired.

Strikeskids
  • 3,932
  • 13
  • 27
1

try using bind() and unbind() like this: DEMO

jQuery(document).ready(function ($) {
    $(".crossY").on("mousedown", function (e) {
        var j = $(this);
        $(document).bind("mousemove", function (e) {
            j.css({
                "top": e.pageY-10,
                "left": e.pageX-10
            });
        });
    })

    $(".crossY").on("mouseup", function (e) {
        var j = $(this);
        $(document).unbind("mousemove");
    });
});
Amin Jafari
  • 7,157
  • 2
  • 18
  • 43
0

Try

jQuery(document).ready(function ($) {
$(".crossY").on("mousedown", function (e) {
    var j = $(this);
    $(document).on("mousemove", function (e) {
        j.css({
            "top": e.pageY,
            "left": e.pageX
        });
    });
})

$(".crossY").on("mouseup", function (e) {
    var j = $(this);
    $(document).off("mousemove");
});

});

Mindastic
  • 4,023
  • 3
  • 19
  • 20