Creating a right-click contextual menu in JavaScript

Written by
Published on

Right click contextual menu's are a great way to hide menu items that are less commonly used, and that you want to keep out of sight until a user decides that they need to use them.

There is no native contextual-menu support in HTML just yet, which means that you will have to build it from the ground-up yourself.

Lucky for us, JavaScript provides the 'contextmenu' event handler which will handle detecting when the user has performed a right-click.

So let's get started.

Creating the menu-items

Let's start off by creating a list of JSON object that will house all of the menu-items that are going to be rendered inside of the context menu.

This will make updating the links a more streamlined process later on. And if you have multiple context menu's that you need to generate, you could then simply just create another collection and point your menu to that one.


    var contextmenu = [{
    Text: 'Link 1',
    Url: 'http://www.google.com',
    Action: function(){
	alert('hello world');
    }
},

{
    Text: 'Link 2',
    Url: 'http://www.google.com',
    Action: function(){
	alert('hello world');
    }
},

{
    Text: 'Link 3',
    Url: 'http://www.google.com',
    Action: function(){
	alert('hello world');
    }
}
];

For the sake of this article, I will only bind the 'contextmenu' event to a single element. You typically DO NOT want to hijack the right-click menu that the browser provides from the user. But you can bind it to individual elements, which is the approach that I will be showing.

Next up, let's load these menu-items to the context menu.

Creating the menu

For the sake of performance, we can create the new context menu on the page pre-loaded and then simply hide it by default. Once the user performs the right-click event, we can simply toggle the display of the menu to show it, and once again hide it on left-click.

Add the following element somewhere near the bottom of the page. Don't worry about placement, as it will be set to position: fixed in the CSS that follows.

<div class='context-menu' id='context1'></div>

Notice that it's empty. And that's because we'll dynamically populate it when the user right-clicks anywhere in the parent.

Here is the CSS needed to have it render fixed on the page.


  .context-menu{
        position: fixed;
        display: none;
        width: 140px;
        box-shadow: 2px 2px 9px #aaa;
        overflow: hidden;
        border:solid 1px #aaa;
    }

    .context-menu > div{
            padding: 10px;
            background: #eee;
            border-bottom: solid 1px #aaa;
            font-size: 11pt;
            cursor:pointer;
        }

        .context-menu > div:hover{
            background:#fff;
        }

        .context-menu.show{
            display:block;
        }

Next up, let's render the menu items from the contextmenu array defined in the beginning.

Render the menu items

While you can render the menu just one time during the beginning page loading phase, I will load the menu on each mouse click and I will explain why right after.

The renderContextMenu function will take 2 arguments, the first being the array of menu-items that we will use to bind the menu, and the second will be the DOM element that we are binding to.

Notice that the menu-item also binds the click event to whatever function property is assigned.

 function renderContextMenu(menu, context){
    context.innerHTML ='';

    menu.forEach(function(item){
            let menuitem = document.createElement('div');
            menuitem.innerHTML = item.Title;
            menuitem.addEventListener('click', item.Action);

            context.appendChild(menuitem);
        });
}

And as mentioned, we will call the renderContextMenu function each time that the user right-clicks.


     window.addEventListener('load', function(){
        document.getElementById('parent').addEventListener('contextmenu', function(e){
            e.preventDefault();
            renderContextMenu(menu, document.getElementById('context'));

            // position menu at the right-click cursor
            document.getElementById('context').style.left = e.clientX + 'px';
            document.getElementById('context').style.top = e.clientY + 'px';
            document.getElementById('context').classList.add('show');
        });

        document.getElementById('parent').addEventListener('click', function(e){
            e.preventDefault();
            document.getElementById('context').classList.remove('show');
        });
    });
        

So why load the items each time the user right-clicks? Well, the main point of a contextual menu is to be just that. Contextual. Which means that it should respond to wherever it is that you are clicking on.

If you are clicking on a text editor for example then you'll want menu items associated with editing. If you are right clicking on an image, then you might want "image" related actions It's all about the context. Which means that you'll want to render the menu in real-time.

Clearing the menu

And the last, but the simplest, is to simply get rid of the menu when a user is done with it. And we can do that by toggling off the 'show' class that was added during the render event.

Also note that to mimic the current logic of rendering a contextual menu, you'll more than likely want to clear it during a left-click event. For this, we can add another event-handler to the parent element to capture a standard mouse click.

document.getElementById('paragraph1').addEventListener('click', function(e){
	document.getElementById('context').classList.remove('show');
}

And there you have it. A quick right-click contextual menu implementation that you can use as a base for your own projects.

Leave a comment

No messages posted yet

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post