How to create custom contextmenu

How to create custom contextmenu

2023-02-10
2 min read

Step 1: Add html code

html
<div>
  <div
    id="context-menu"
    class="context-menu hide"
  >
    <div>
      Context menu...!
    </div>
  </div>
  <div id="context-menu-test">
    Right click here
  </div>
</div>

id can be different based on your element, but you have to change some javaScript codes

Step 2: Add CSS

css
.context-menu {
  z-index: 1000;
  position: absolute;
  background: white;
  border: 0.1rem solid black;
  padding: 4px;
}

.hide {
  display: none;
}

Add absolute for position with high level of z-index. Other can be changed based on your program.

Step 3: Add display and hide handler

The contextmenu event fires when user try to open a context menu. The event is typically triggered by clicking the right mouse button.

Step 3.1: Add eventListener

js
document.querySelector('#context-menu-test')
  .addEventListener('contextmenu', contextmenuHandler)

Add eventListener to element that user will click right mouse button.

Step 3.2: contextmenu event handler function

js
const contextmenuHandler = (event) => {
  event.preventDefault()
  const contextmenu = document.querySelector('#context-menu')
  if (!contextmenu) return

  contextmenu.classList.remove('hide')
  contextmenu.style.top = event.y + 'px'
  contextmenu.style.left = event.x + 'px'
}
  • preventDefault() method will disable original contextmenu.
  • Remove hide class to display context menu element
  • top and left are for displaying the contextmenu on position that user click right mouse button.

Step 4 Add click outside handler

In order to hide contextmenu when user click outside, click event for window is required.

Step4.1: Change contextmenu event handler function

js
const contextmenuHandler = (event) => {
  // ...
  window.addEventListener('click', clickOutsideHandler)
}

Add customclick event to window.

js
const clickOutsideHandler = (event) => {
  event.preventDefault()
  const contextmenu = document.querySelector('#context-menu')
  if (!contextmenu) return
  if (contextmenu.contains(event.target)) return

  contextmenu.classList.add('hide')

  window.removeEventListener('click', clickOutsideHandler)
}
  • contextmenu.contains(event.target) is used for passing to hide element
  • Add hide class to hide contextmenu
  • After click event fire, removing the event from window is recommended.

Full Source code

html
<div>
  <div
    id="context-menu"
    class="context-menu hide"
  >
    <div>
      Context menu...!
    </div>
  </div>
  <div id="context-menu-test">
    Right click here
  </div>
</div>
js
const clickOutsideHandler = (event) => {
  event.preventDefault()
  const contextmenu = document.querySelector('#context-menu')
  if (!contextmenu) return

  contextmenu.classList.add('hide')

  window.removeEventListener('click', clickOutsideHandler)
}

const contextmenuHandler = (event) => {
  event.preventDefault()
  const contextmenu = document.querySelector('#context-menu')
  if (!contextmenu) return

  contextmenu.classList.remove('hide')
  contextmenu.style.top = event.y + 'px'
  contextmenu.style.left = event.x + 'px'

  window.addEventListener('click', clickOutsideHandler)
}

document.querySelector('#context-menu-test')
  .addEventListener('contextmenu', contextmenuHandler)
css
.context-menu {
  z-index: 1000;
  position: absolute;
  background: white;
  border: 0.1rem solid black;
  padding: 4px;
}

.hide {
  display: none;
}

codepen

ref

Free open source project made by Youngjin