26

How is it possible to detect with an eventListener when mousemove has finished?

document.AddEventListener('mousemove', startInteractionTimer, false);

function startInteractionTimer(){
  clearInterval(touchInterval);
  touchInterval = setInterval(noAction, 6000);
}

I want to start the function startInteractionTimer immediately after the mousemove has ended and I would like to catch that. On the code example above, it is starting if the mouse is moved.

Thanks

Edit: Alright, I answered my own question and the script above --^ is just fine.

supersize
  • 13,764
  • 18
  • 74
  • 133
  • doesn't your example exactly do that - if the mouse is not moved for a certain time, it calls `noAction`? (there is not stop event for `mousemove` how should this be detected? this can only be detected if it is in combination with `mousedown` and `mouseup` if e.g. for dragging) – t.niese Feb 25 '13 at 12:25
  • MouseMove event fires when cursor is already stopped. So you can detect if cursor isn't moving for some time and do what you want – Sergio Feb 25 '13 at 12:28
  • no, my example fires the event if the mouse is moved! not after the mousemove has stopped. – supersize Feb 25 '13 at 12:28
  • 1
    @TedMosby thats true, but on each call you clear the interval. so as long as the mouse does to stop for `6000` milliseconds, `noAction` is not called. if the mouse is not moved for 6 secs then `noAction` is called. – t.niese Feb 25 '13 at 12:43
  • http://richardscarrott.co.uk/posts/view/jquery-mousestop-event -- https://github.com/richardscarrott/jquery-mousestop-event – Joonas Feb 25 '13 at 13:04
  • haha t.niese. this is kind of weird but it seems that i did not save the file! it works like you said, sry for the trouble! thanks – supersize Feb 25 '13 at 13:11

3 Answers3

18

You could always make a custom event for it:

(function ($) {
    var timeout;
    $(document).on('mousemove', function (event) {
        if (timeout !== undefined) {
            window.clearTimeout(timeout);
        }
        timeout = window.setTimeout(function () {
            // trigger the new event on event.target, so that it can bubble appropriately
            $(event.target).trigger('mousemoveend');
        }, 100);
    });
}(jQuery));

Now you can just do this:

$('#my-el').on('mousemoveend', function () {
    ...
});

Edit:

Also, for consistency with other jQuery events:

(function ($) {
    $.fn.mousemoveend = function (cb) {
        return this.on('mousemoveend', cb);
    });
}(jQuery));

Now you can:

$('#my-el').mousemoveend(fn);
Nathan MacInnes
  • 11,033
  • 4
  • 35
  • 50
13

You could try setting/clearing a timeout solely to detect the end of moving the mouse...

var x;
document.addEventListener('mousemove', function() { 
    if (x) clearTimeout(x); 
    x = setTimeout(startInteractionTimer, 200); 
}, false);

How long you want to wait is up to you. I don't know how long you want to say is "the end of a mousemove"

Example: http://jsfiddle.net/jeffshaver/ZjHD6/

Jeff Shaver
  • 3,315
  • 18
  • 19
11

Here is another custom-event solution, but without jQuery. It creates an event called mousestop which will be triggered on the element that the mouse pointer is on. It will bubble up like other mouse events.

So once you have that piece of code included, you can add event listeners to any element with addEventListener('mousestop', fn):

(function (mouseStopDelay) {
    var timeout;
    document.addEventListener('mousemove', function (e) {
        clearTimeout(timeout);
        timeout = setTimeout(function () {
            var event = new CustomEvent("mousestop", {
                detail: {
                    clientX: e.clientX,
                    clientY: e.clientY
                },
                bubbles: true,
                cancelable: true
            });
            e.target.dispatchEvent(event);
        }, mouseStopDelay);
    });
}(1000));

// Example use
document.getElementById('link').addEventListener('mousestop', function(e) {
    console.log('You stopped your mouse while on the link');
    console.log('Mouse coordinates are: ', e.detail.clientX, e.detail.clientY);
    // The event will bubble up to parent elements.
});
<h1>Title</h1>
<div>
    content content<br>
    <a id="link" href="#">stop your mouse over this link for 1 second</a><br>
    content content content
</div>
trincot
  • 317,000
  • 35
  • 244
  • 286