0

I have assigned a "mousemove" event on some div elements. Those elements might overlap each other due to an animation process, so several "mousemove" events could be called at once by moving the mouse over the overlapping parts.

The problem is that two triggered "mousemove" events can lead to conflicting decisions. Hence, I would like to make a decision based on ALL elements that are concerned by the "mousemove" event, when such an event occur for at least one of them.

My question is : do you know an efficient way to do it ?

Thanks !

Backslash36
  • 755
  • 1
  • 13
  • 28
  • I would suggest doing both events at once inside the event handler, and just check on the id or a class or something before you perform the second event's code. That way you only have one mousemove event. – Seano666 Aug 28 '13 at 01:08
  • Could you produce a fiddle on jsfiddle.net? – cgatian Aug 28 '13 at 01:09

1 Answers1

0

If I understand the q correctly, you want to synchronize the execution of mousemove events for each div. There are hacky ways to do it, though the best would be to change your HTML markup, so you don't have overlaps.

Anyway, for your case, you could do the following:

var g_focusDivId = "";

function onMouseMove(e)
{
    if (g_focusDivId != "" && g_focusDivId != e.target.id)
         return; // Deciding to not exec any other mouse moves

    g_focusDivId = e.target.id;

    // Do your stuff

    g_focusDivId = "";
}

This, of course, assumes that JS event handling is single-threaded, which is not always true: Is JavaScript guaranteed to be single-threaded?

The alternative is to do this (I have not tried this). I am using a queue to run the events in sequence on a single method. Much more controlled, but it may lead to some events getting processed late.

var g_syncEventQueue = new Array();

function onMouseEvent(e)
{
    g_syncEventQueue.push(e);
}

function queueListenerProc()
{
    if (g_syncEventQueue.size() > 0)
    {
       var evt = g_syncEventQueue[0];
       g_syncEventQueue = g_syncEventQueue.splice(0, 1);
       return queueListenerProc(); // Immediately process the next event
    }

    setTimeout("queueListenerProc()", 1000);
}

queueListenerProc(); // Not ideal because it keeps running without an exit condition.
Community
  • 1
  • 1
Vivek
  • 428
  • 2
  • 13
  • Thank you for you answer ! The second solution you gave is the closest to what I would like to achieve. The thing is, as you said, there is no exit condition to the function, and I would like to have something fast and efficient. Is there a way to get a list of all elements concerned by the event ? That would solve the trick in my opinion. – Backslash36 Aug 28 '13 at 01:41
  • Each event (the e argument in onMouseMove) pertains to one target only. queueListenerProc ensures that it clears the queue of events as fast as possible. Only if the queue is empty, it sets the timeout. If you have some sort of a stop point, it will probably make it easier to implement an exit. The entry and exit have to be handled in some synchronized way. – Vivek Aug 28 '13 at 02:24
  • If you are OK with taking a chance with the first one, I would just modify it to maintain another queue (similar to the second one) and add to it if the first IF succeeds. Thereafter, apart from processing the current event in onMouseMove, you can also iterate over the array and process that too. This approach scares me a bit though. It's hacky. As such, the second approach may not be as bad as you think, since it exits pretty quickly when the queue is empty. – Vivek Aug 28 '13 at 02:27
  • I understand what you mean. Actually the problem with your solution is that I don't know when the queue actually ends (that is, I have no way to know when every element concerned by the event is added to the queue). More precisely, I would need the number of elements to be added to the queue. If I can get this information, then your solution is fine for me ! – Backslash36 Aug 28 '13 at 09:15
  • So, you need to know precisely how many div elements are currently firing? You could maintain another map (basically an object) for that where the key is the div id. Let the value of the map be a ref count on the number of events added to the queue. So, every time you add an object to the queue in onMouseEvent, just update this map. You can maintain the map like so: http://stackoverflow.com/questions/6298169/how-to-create-a-map-object-in-a-javascript – Vivek Aug 28 '13 at 09:58
  • @Backslash36, if this works for you, would you mind marking the answer? Thanks! :-) – Vivek Sep 01 '13 at 05:06