Search code examples
javascriptevent-handlingcontextmenu

Determine if a mousedown will trigger contextmenu in JS


I want to handle mousedown events, but not those which will trigger immediately later a contextmenu event.

As mousedown events are dispatched before contextmenu events, I can't "flag" the event somehow (e.g. by recording its timeStamp) in the contextmenu handler.

Of course, I can check event.ctrlKey in the mousedown handler, but that misses some other ways a context menu can be triggered (and, I assume, platform specific details). So how can I determine for sure if a contextmenu will follow?


Solution

  • You're right, that there are different ways to trigger the contextmenu event, however the issue, as you describe it, melts down to the case "mousedown and contextmenu".

    In general a contextmenu event will follow a mousedown when the secondary mouse button was pressed. A special case for Mac we'll discuss later.


    NB: The secondary button is usually the right one, when not configured otherwise. Left-handers e.g. will prefer the left mouse button. However, that's unimportant here, so lets stick to the configuration-independent term secondary button.


    Now, you can check in your mousedown handler which button has been pressed, querying the button property of a MouseEvent object. The secondary button is represented by the number 2. So if MouseEvent.button == 2 in the mousedown handler, than don't execute that stuff you want to skip in case a contextmenu event was triggered.

    Further, on Apple devices one can also employ the primary -- i.e. usually but not necessarily left -- mouse button while pressing the Control key. So the complete check in the mousedown handler on a MouseEvent object e is:

    e.button == 2 || (e.button == 0 && e.ctrlKey)
    

    If this is true, a contextmenu event will (right-click) or may (left-click + ctrl) follow. On Windows and Linux a left-click with Control will be misinterpreted as a click event after mouseup. Either hope that no ones come to that idea on Windows or Linux, or catch that case.

    This should cover all mouse-related triggers for contextmenu on common operating systems, i.e. Windows, Linux and Mac.


    As aarvinr pointed out in his comment, one can also employ the MouseEvent.buttons property for this purpose.