0

I have an event that is triggered when a user has their mouse over a div element and while they're moving the mouse over the element. However, I can't seem to find a way to trigger an event when the mouse stops moving. For example, the event I'm working on checks if the user has the mouse over a div, if it is, then another element is shown and follows the mouse around. When the user leaves the div, the shown element is hidden. The way it works now is, I have the shown element showing and following the mouse around on the moused-over div, but it's not exactly what I want. I'd like to have it not show when the mouse is moving, but show when the mouse has stopped moving.

HTML

<div class="tooltip"><p></p></div>
<div class="holder" id="1"></div>
<div class="holder" id="2"></div>

CSS

.holder{
    display: block;
    float: left;
    margin-bottom: 0.25%;
    width: 100%;
    height: 200px;
    cursor: pointer;
    border-top: 1px solid rgb(100, 100, 0);
    border-bottom: 1px solid rgb(100, 100, 0);
}
.tooltip{
    position: absolute;
    display: none;
    width: 150px;
    background-color: white;
    z-index: 5;
}

JS

var holder = document.getElementsByClassName("holder");
var tooltip = document.getElementsByClassName("tooltip")[0];
for(var i = 0; i < holder.length; i++){
    var moving;
    holder[i].onmouseover = function(ev){
        moving = false
        tooltip.style.display = "block";
        tooltip.style.top = ev.clientY;
        tooltip.style.left = ev.clientX;
    }
    holder[i].onmouseout = function(ev){
        moving = false
        tooltip.style.display = "none";
        tooltip.style.top = ev.clientY;
        tooltip.style.left = ev.clientX;
    }
    holder[i].onmousemove = function(ev){
        moving = true;
    }

    if(moving){
        tooltip.style.display = "none";
        tooltip.style.top = ev.clientY;
        tooltip.style.left = ev.clientX;
    }
}
Robert
  • 624
  • 2
  • 8
  • 19
  • 2
    You could implement some kind of timeout.. while mouse moving you clean and re-spawn a function.. – Erik Simonic Sep 28 '16 at 19:22
  • Maybe this would help: http://stackoverflow.com/questions/24727394/are-there-any-javascript-jquery-events-that-are-like-an-onmousestop-or-any-eve – Max G. Sep 28 '16 at 19:23
  • Awesome, thanks Erik and Max – Robert Sep 28 '16 at 19:27
  • Look for a `debounce` function instead of direct execution of the callback on the event. It delays execution for a short period. If a new event is called again in that period the callback is not performed, but the cycle starts again. Only after the last event the callback is executed. I your case, when the mouse stopped moving. – Kwebble Sep 28 '16 at 19:43
  • @Robert, I added a jQuery-less answer to the referenced http://stackoverflow.com/questions/24727394/are-there-any-javascript-jquery-events-that-are-like-an-onmousestop-or-any-eve, since your question did not have the `jquery` tag. – trincot Sep 28 '16 at 20:04

2 Answers2

1

One naive approach would be set a timer when onmousemove is called. When the timer expires, do the hiding. When onmousemove is called again, reset the timer's timeout.

It's a judgement call for the application to make as to when someone stops moving the mouse. Technically a continuous movement of a mouse translates into a mouse move event per pixel.

You need to be a bit smart in doing this because onmousemove gets called a lot. So maybe something like this:

var mouseStartedMoving = false;
var mouseMoved = false;
const MINIMUM_MOUSE_MOVE_TIME = 100;

setInterval(() => { 
   if(!mouseMoved && mouseStartedMoving) {
       //Mouse stopped moving
       //Do CSS change
       mouseStartedMoving = false;
   }
   mouseMoved = false;
}, MINIMUM_MOUSE_MOVE_TIME);

holder[i].onmousemove = function(ev){
  mouseStartedMoving = true;
  mouseMoved = true;
}
Philip Whitehouse
  • 4,293
  • 3
  • 23
  • 36
0

You can do this using "setTimeout" function.

When you track mouse moves set "mouseMoved" to current millis. And then you do something like this:

setTimeout(function(){ 

    var now = new Date();
    var nowMillis = d.getMilliseconds();
    var timeDiff = nowMillis - mouseMoved;
    if (timeDiff > 3000)
        alert("mouse stopped moving for 3 seconds"); 
}, 3000);