The right mouse button triggers a context menu to appear in web browsers. As developers, we often need to capture the right click event and take some action when users right click on page elements. This comprehensive guide explains how to fully detect and handle right click events in JavaScript.
What is the Context Menu Event?
The contextmenu event fires when the user clicks the right mouse button to trigger the browser‘s context menu. This opens a menu providing options like copy, paste etc related to the current context.
As per MDN web docs:
The contextmenu event fires when the user tries to open a context menu. This allows the development of custom context menus for web applications.
Context menus act as a quick way to access common commands without needing to navigate UI menus. Over 74% of users utilize context menus to speed up interactions with web applications.
Why Capture the Right Click Event?
Here are the most common use cases for capturing right click events in JavaScript:
-
To display custom context menus instead of the default browser provided menu
Many apps require special item options, nested sub-menus and other domain-specific commands that go beyond the native menu.
-
Implement special effects like preview panels, rating dialogs etc on right clicking specific page elements
For example, an image gallery site can show an info overlay on right clicking photos.
-
Override or disable the default right click behavior
Some apps need to block the default menu from appearing to avoid confusing options.
-
Track right click usage for advanced analytics and click heatmaps
This helps understand usage patterns to improve page designs.
-
Display debugging alerts and messages during development
Logging details on right clicks helps troubleshoot issues faster.
So having the ability to capture and handle this event opens up many possibilities for better, richer behaviors and customizations.
Detecting Right Click Events in JavaScript
The easiest way to listen for right clicks is to attach an event handler for the browser‘s native "contextmenu" event using JavaScript.
Using addEventListener()
We can call addEventListener()
on the window
, document
or other specific DOM elements to listen for contextmenu events:
// Attach handler to document
document.addEventListener(‘contextmenu‘, (event) => {
// Code to handle right click event
});
Now whenever the user right clicks within the attached element, our callback function will be executed.
For example, the following will display an alert popup whenever the user right clicks anywhere on the page:
window.addEventListener(‘contextmenu‘, (event) => {
alert(‘Right mouse button clicked!‘);
});
Here is this live demo:
The alert popup demonstrates how we can run JavaScript code in response to the contextmenu event.
The Event Object
The callback function is passed an Event object parameter (typically named event
) containing useful information like:
event.pageX
,event.pageY
– mouse cursor positionevent.clientX
,event.clientY
– relative to viewportevent.target
– the DOM element mouse clicked onevent.preventDefault()
– prevents default browser menu
For example, we can print details to console instead of alert:
window.addEventListener(‘contextmenu‘, (event) => {
console.log(event);
console.log(`Right clicked at
PageX: ${event.pageX}
PageY: ${event.pageY}`);
});
This allows us to dynamically position menus or implement logic based on event properties.
Next let‘s see how the event can be used to customize default behavior.
Disabling the Default Browser Menu
We can prevent the default context menu from appearing by calling event.preventDefault()
:
window.addEventListener(‘contextmenu‘, (event) => {
event.preventDefault();
console.log(‘Default menu disabled!‘);
});
Now right clicking on the page will not show the standard browser provided context menu.
This allows replacing the original menu with a custom one (covered ahead).
Creating a Custom Context Menu
To display a completely custom menu instead of the browser‘s default, we can:
- Prevent the default menu using
event.preventDefault()
- Dynamically generate HTML for our custom menu
- Append this menu component into the DOM
- Position it based on the mouse coordinates
- Remove the menu when it loses focus
For example:
// Menu template as HTML
var menu = `
<div id="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
`;
// Add event listener
document.addEventListener(‘contextmenu‘, (event) => {
event.preventDefault();
// Create menu DOM dynamically
let menuDiv = document.createElement(‘div‘);
menuDiv.innerHTML = menu;
document.body.appendChild(menuDiv);
// Position under mouse
menuDiv.style.left = `${event.pageX}px`;
menuDiv.style.top = `${event.pageY}px`;
});
// Remove menu element when invisible
document.addEventListener(‘click‘, () => {
document.querySelector(‘#menu‘)?.remove();
})
Now instead of the default menu, our custom context menu appears!
The key advantages over default menus are:
- Can contain interactive JavaScript elements like toggles, datepickers etc
- Dynamic item generation based on application state
- Icons, images and custom styling for brand consistency
- Nested submenus for complex application functionality
So building custom components provides greater flexibility.
Next we‘ll cover some advanced implementations.
Advanced Right Click Event Handling
The basic listener pattern serves most use cases for responding to right clicks. But for more complex interactivity, here are some tips:
1. Multiple Handlers on Same Event
We can attach multiple event handlers for the same contextmenu
event:
// 1st handler
document.addEventListener(‘contextmenu‘, (event) => {
// Shared logic
});
// 2nd handler
document.addEventListener(‘contextmenu‘, (event) => {
// Specific logic
});
These allow separation of cross-cutting and specific concerns:
Image source: LogRocket
For example – one for analytics, another for DOM updates.
2. Use Capture vs Bubble Phase
Event propagation happens in 2 phases:
- Capturing – goes down from
window
->document
-> target element - Bubbling – bottoms-up from target to
document
towindow
By default handlers are called in the bubbling flow.
We can force the capture phase using an options object:
document.addEventListener(‘contextmenu‘, (event) => {
// Handling logic
}, {capture: true});
This ensures the handler is triggered first before bubble propagation.
3. Cleaning Up Listeners
To avoid memory leaks, we must clean up unused event listeners by calling removeEventListener()
:
// Attach listener
document.addEventListener(‘contextmenu‘, handler);
// When no longer required
document.removeEventListener(‘contextmenu‘, handler);
This best practice releases references to the handler function for garbage collection.
Accessibility Considerations
Relying solely on right click events has some downsides:
- Not keyboard accessible – purely mouse based
- Screen readers may not handle custom menus properly if not coded correctly
Therefore, we must ensure keyboard and assistive technology support:
✅ Use onkeydown
event for arrow keys directing screen readers
✅ Support Enter
and Spacebar
keys to activate items
✅ Follow WAI-ARIA authoring practices for custom widgets
This ensures maximum accessibility for users with disabilities – a must for professional web development.
Common Use Cases
Beyond basic menus, developers utilize the contextmenu event for many creative purposes:
Browser Extensions
Browser extensions like productivity tools and accessibility enhancers often extend native context menus with extra options.
For example, the Widemage extension adds a "Open Image in New Tab" item:
Detecting contextmenu
allows injecting these new items.
JavaScript Frameworks
All popular frameworks like React, Angular and Vue provide components for conditionally displaying custom context menus.
For example, React has the react-contextmenu NPM module for configurable menus.
Libraries abstract away direct DOM manipulation, letting developers declaratively express right click handling logic.
Drawing Apps
Online whiteboard tools utilize right clicks for accessing color palettes, stroke settings, shape tools etc.
For example, the Excalidraw whiteboard app shows this robust menu:
So alternatives to default menus enhance specialized drawing use cases.
There are many other advanced custom UI scenarios for maps, 3D tools etc.
Mobile Considerations
Mobile devices like phones and tablets lack physical mouse buttons. But the contextmenu event can still be leveraged:
Long Press Gestures
A long press touch typically triggers a similar contextual menu to appear:
So the right click can be emulated via touch and hold gestures.
We must adjust positioning based on touch
events rather than mouse coordinates.
Responsiveness
For responsive cross-device sites, the menu implementation should adapt based on viewport width breakpoints.
More specifically – build a compact radial dial menu for smaller touch interfaces rather than cascading flyouts.
This ensures usable context options without excessive panning required on mobile.
Browser Compatibility
The contextmenu event enjoys excellent cross browser support:
Browser | Supported Versions |
---|---|
Chrome | Yes |
Firefox | Yes |
Safari | Yes |
Edge | Yes |
IE | 9+ |
Legacy IE browsers do not expose contextmenu events directly.
A fallback is listening for onclick
events and checking event.button === 2
to detect the right mouse button click.
So robust cross browser handling is possible with small workarounds.
Conclusion
Detecting right click events allows implementing highly interactive custom menus, UI panels and special effects.
The key highlights are:
✅ Use addEventListener()
to listen for contextmenu
events
✅ event.preventDefault()
prevents the default browser menu
✅ Dynamically build custom menu components
✅ Position menus based on mouse coordinates
✅ Ensure proper keyboard and screen reader accessibility
✅ Remember to remove unused event handlers
I hope this guide gave you a firm grasp of capturing and handling right click events using modern JavaScript. Let me know if you have any other questions!