I've a few websites like google-docs and map-quest that have custom drop down menus when you right-click. Somehow they override the browser's behavior of drop-down menu, and I'm now sure exactly how they do it. I found a jQuery plugin that does this, but I'm still curious about a few things:
See several custom-context menus in action
To make this HTML menu visible when right-clicking in the browser, we need to listen for contextmenu events. We can bind the event listener directly on the document or we can limit the area that a user can right-click to see the custom context menu. In our example, the area for right-click is the entire body element.
To do this, we will use two properties pageX and pageY of the mouse click event which will give us the coordinates where the right button was clicked. We will hide the context menu on the mouse button click if it is already being displayed. JavaScript code: HTML.
Open the app -> Java -> Package -> Mainactivity.In this step, add the code to show the ContextMenu. Whenever the app will strat make a long click on a text and display the number of options to select of them for specific purposes. Comments are added inside the code to understand the code in more detail.
Right-click on the “shell” key, and then choose New > Key from the menu. Give the new key the name that you want to show up on the desktop context menu.
I know this question is very old, but just came up with the same problem and solved it myself, so I'm answering in case anyone finds this through google as I did. I based my solution on @Andrew's one, but basically modified everything afterwards.
EDIT: seeing how popular this has been lately, I decided to update also the styles to make it look more like 2014 and less like windows 95. I fixed the bugs @Quantico and @Trengot spotted so now it's a more solid answer.
EDIT 2: I set it up with StackSnippets as they're a really cool new feature. I leave the good jsfiddle here for reference thought (click on the 4th panel to see them work).
New Stack Snippet:
// JAVASCRIPT (jQuery)
// Trigger action when the contexmenu is about to be shown
$(document).bind("contextmenu", function (event) {
// Avoid the real one
event.preventDefault();
// Show contextmenu
$(".custom-menu").finish().toggle(100).
// In the right position (the mouse)
css({
top: event.pageY + "px",
left: event.pageX + "px"
});
});
// If the document is clicked somewhere
$(document).bind("mousedown", function (e) {
// If the clicked element is not the menu
if (!$(e.target).parents(".custom-menu").length > 0) {
// Hide it
$(".custom-menu").hide(100);
}
});
// If the menu element is clicked
$(".custom-menu li").click(function(){
// This is the triggered action name
switch($(this).attr("data-action")) {
// A case for each action. Your actions here
case "first": alert("first"); break;
case "second": alert("second"); break;
case "third": alert("third"); break;
}
// Hide it AFTER the action was triggered
$(".custom-menu").hide(100);
});
/* CSS3 */
/* The whole thing */
.custom-menu {
display: none;
z-index: 1000;
position: absolute;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 5px;
padding: 0;
}
/* Each of the items in the list */
.custom-menu li {
padding: 8px 12px;
cursor: pointer;
list-style-type: none;
transition: all .3s ease;
user-select: none;
}
.custom-menu li:hover {
background-color: #DEF;
}
<!-- HTML -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.js"></script>
<ul class='custom-menu'>
<li data-action="first">First thing</li>
<li data-action="second">Second thing</li>
<li data-action="third">Third thing</li>
</ul>
<!-- Not needed, only for making it clickable on StackOverflow -->
Right click me
Note: you might see some small bugs (dropdown far from the cursor, etc), please make sure that it works in the jsfiddle, as that's more similar to your webpage than StackSnippets might be.
As Adrian said, the plugins are going to work the same way. There are three basic parts you're going to need:
1: Event handler for 'contextmenu'
event:
$(document).bind("contextmenu", function(event) {
event.preventDefault();
$("<div class='custom-menu'>Custom menu</div>")
.appendTo("body")
.css({top: event.pageY + "px", left: event.pageX + "px"});
});
Here, you could bind the event handler to any selector that you want to show a menu for. I've chosen the entire document.
2: Event handler for 'click'
event (to close the custom menu):
$(document).bind("click", function(event) {
$("div.custom-menu").hide();
});
3: CSS to control the position of the menu:
.custom-menu {
z-index:1000;
position: absolute;
background-color:#C0C0C0;
border: 1px solid black;
padding: 2px;
}
The important thing with the CSS is to include the z-index
and position: absolute
It wouldn't be too tough to wrap all of this in a slick jQuery plugin.
You can see a simple demo here: http://jsfiddle.net/andrewwhitaker/fELma/
<!DOCTYPE html>
<html>
<head>
<title>Right Click</title>
<link href="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.css" rel="stylesheet" type="text/css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.contextMenu.js" type="text/javascript"></script>
<script src="https://swisnl.github.io/jQuery-contextMenu/dist/jquery.ui.position.min.js" type="text/javascript"></script>
</head>
<body>
<span class="context-menu-one" style="border:solid 1px black; padding:5px;">Right Click Me</span>
<script type="text/javascript">
$(function() {
$.contextMenu({
selector: '.context-menu-one',
callback: function(key, options) {
var m = "clicked: " + key;
window.console && console.log(m) || alert(m);
},
items: {
"edit": {name: "Edit", icon: "edit"},
"cut": {name: "Cut", icon: "cut"},
copy: {name: "Copy", icon: "copy"},
"paste": {name: "Paste", icon: "paste"},
"delete": {name: "Delete", icon: "delete"},
"sep1": "---------",
"quit": {name: "Quit", icon: function(){
return 'context-menu-icon context-menu-icon-quit';
}}
}
});
$('.context-menu-one').on('click', function(e){
console.log('clicked', this);
})
});
</script>
</body>
</html>
here is an example for right click context menu in javascript: Right Click Context Menu
Used raw javasScript Code for context menu functionality. Can you please check this, hope this will help you.
Live Code:
(function() {
"use strict";
/*********************************************** Context Menu Function Only ********************************/
function clickInsideElement( e, className ) {
var el = e.srcElement || e.target;
if ( el.classList.contains(className) ) {
return el;
} else {
while ( el = el.parentNode ) {
if ( el.classList && el.classList.contains(className) ) {
return el;
}
}
}
return false;
}
function getPosition(e) {
var posx = 0, posy = 0;
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
} else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return {
x: posx,
y: posy
}
}
// Your Menu Class Name
var taskItemClassName = "thumb";
var contextMenuClassName = "context-menu",contextMenuItemClassName = "context-menu__item",contextMenuLinkClassName = "context-menu__link", contextMenuActive = "context-menu--active";
var taskItemInContext, clickCoords, clickCoordsX, clickCoordsY, menu = document.querySelector("#context-menu"), menuItems = menu.querySelectorAll(".context-menu__item");
var menuState = 0, menuWidth, menuHeight, menuPosition, menuPositionX, menuPositionY, windowWidth, windowHeight;
function initMenuFunction() {
contextListener();
clickListener();
keyupListener();
resizeListener();
}
/**
* Listens for contextmenu events.
*/
function contextListener() {
document.addEventListener( "contextmenu", function(e) {
taskItemInContext = clickInsideElement( e, taskItemClassName );
if ( taskItemInContext ) {
e.preventDefault();
toggleMenuOn();
positionMenu(e);
} else {
taskItemInContext = null;
toggleMenuOff();
}
});
}
/**
* Listens for click events.
*/
function clickListener() {
document.addEventListener( "click", function(e) {
var clickeElIsLink = clickInsideElement( e, contextMenuLinkClassName );
if ( clickeElIsLink ) {
e.preventDefault();
menuItemListener( clickeElIsLink );
} else {
var button = e.which || e.button;
if ( button === 1 ) {
toggleMenuOff();
}
}
});
}
/**
* Listens for keyup events.
*/
function keyupListener() {
window.onkeyup = function(e) {
if ( e.keyCode === 27 ) {
toggleMenuOff();
}
}
}
/**
* Window resize event listener
*/
function resizeListener() {
window.onresize = function(e) {
toggleMenuOff();
};
}
/**
* Turns the custom context menu on.
*/
function toggleMenuOn() {
if ( menuState !== 1 ) {
menuState = 1;
menu.classList.add( contextMenuActive );
}
}
/**
* Turns the custom context menu off.
*/
function toggleMenuOff() {
if ( menuState !== 0 ) {
menuState = 0;
menu.classList.remove( contextMenuActive );
}
}
function positionMenu(e) {
clickCoords = getPosition(e);
clickCoordsX = clickCoords.x;
clickCoordsY = clickCoords.y;
menuWidth = menu.offsetWidth + 4;
menuHeight = menu.offsetHeight + 4;
windowWidth = window.innerWidth;
windowHeight = window.innerHeight;
if ( (windowWidth - clickCoordsX) < menuWidth ) {
menu.style.left = (windowWidth - menuWidth)-0 + "px";
} else {
menu.style.left = clickCoordsX-0 + "px";
}
// menu.style.top = clickCoordsY + "px";
if ( Math.abs(windowHeight - clickCoordsY) < menuHeight ) {
menu.style.top = (windowHeight - menuHeight)-0 + "px";
} else {
menu.style.top = clickCoordsY-0 + "px";
}
}
function menuItemListener( link ) {
var menuSelectedPhotoId = taskItemInContext.getAttribute("data-id");
console.log('Your Selected Photo: '+menuSelectedPhotoId)
var moveToAlbumSelectedId = link.getAttribute("data-action");
if(moveToAlbumSelectedId == 'remove'){
console.log('You Clicked the remove button')
}else if(moveToAlbumSelectedId && moveToAlbumSelectedId.length > 7){
console.log('Clicked Album Name: '+moveToAlbumSelectedId);
}
toggleMenuOff();
}
initMenuFunction();
})();
/* For Body Padding and content */
body { padding-top: 70px; }
li a { text-decoration: none !important; }
/* Thumbnail only */
.thumb {
margin-bottom: 30px;
}
.thumb:hover a, .thumb:active a, .thumb:focus a {
border: 1px solid purple;
}
/************** For Context menu ***********/
/* context menu */
.context-menu { display: none; position: absolute; z-index: 9999; padding: 12px 0; width: 200px; background-color: #fff; border: solid 1px #dfdfdf; box-shadow: 1px 1px 2px #cfcfcf; }
.context-menu--active { display: block; }
.context-menu__items { list-style: none; margin: 0; padding: 0; }
.context-menu__item { display: block; margin-bottom: 4px; }
.context-menu__item:last-child { margin-bottom: 0; }
.context-menu__link { display: block; padding: 4px 12px; color: #0066aa; text-decoration: none; }
.context-menu__link:hover { color: #fff; background-color: #0066aa; }
.context-menu__items ul { position: absolute; white-space: nowrap; z-index: 1; left: -99999em;}
.context-menu__items > li:hover > ul { left: auto; padding-top: 5px ; min-width: 100%; }
.context-menu__items > li li ul { border-left:1px solid #fff;}
.context-menu__items > li li:hover > ul { left: 100%; top: -1px; }
.context-menu__item ul { background-color: #ffffff; padding: 7px 11px; list-style-type: none; text-decoration: none; margin-left: 40px; }
.page-media .context-menu__items ul li { display: block; }
/************** For Context menu ***********/
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<body>
<!-- Page Content -->
<div class="container">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Thumbnail Gallery <small>(Right click to see the context menu)</small></h1>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
<div class="col-lg-3 col-md-4 col-xs-6 thumb">
<a class="thumbnail" href="#">
<img class="img-responsive" src="http://placehold.it/400x300" alt="">
</a>
</div>
</div>
<hr>
</div>
<!-- /.container -->
<!-- / The Context Menu -->
<nav id="context-menu" class="context-menu">
<ul class="context-menu__items">
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Delete This Photo"><i class="fa fa-empire"></i> Delete This Photo</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Photo Option 2"><i class="fa fa-envira"></i> Photo Option 2</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Photo Option 3"><i class="fa fa-first-order"></i> Photo Option 3</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Photo Option 4"><i class="fa fa-gitlab"></i> Photo Option 4</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Photo Option 5"><i class="fa fa-ioxhost"></i> Photo Option 5</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link"><i class="fa fa-arrow-right"></i> Add Photo to</a>
<ul>
<li><a href="#!" class="context-menu__link" data-action="album-one"><i class="fa fa-camera-retro"></i> Album One</a></li>
<li><a href="#!" class="context-menu__link" data-action="album-two"><i class="fa fa-camera-retro"></i> Album Two</a></li>
<li><a href="#!" class="context-menu__link" data-action="album-three"><i class="fa fa-camera-retro"></i> Album Three</a></li>
<li><a href="#!" class="context-menu__link" data-action="album-four"><i class="fa fa-camera-retro"></i> Album Four</a></li>
</ul>
</li>
</ul>
</nav>
<!-- End # Context Menu -->
</body>
The browser's context menu is being overridden. There is no way to augment the native context menu in any major browser.
Since the plugin is creating its own menu, the only part thats really being abstracted is the browser's context menu event. The plugin creates an html menu based on your configuration, then places that content at the location of your click.
Yes, this is the only way to go about creating a custom context menu. Obviously, different plugins do things slightly different, but they will all override the browser's event and place their own html-based menu in the correct place.
You can watch this tutorial: http://www.youtube.com/watch?v=iDyEfKWCzhg Make sure the context menu is hidden at first and has a position of absolute. This will ensure that there won't be multiple context menu and useless creation of context menu. The link to the page is placed in the description of the YouTube video.
$(document).bind("contextmenu", function(event){
$("#contextmenu").css({"top": event.pageY + "px", "left": event.pageX + "px"}).show();
});
$(document).bind("click", function(){
$("#contextmenu").hide();
});
I know that this is rather old also. I recently had a need to create a context menu that I inject into other sites that have different properties based n the element clicked.
It's rather rough, and there are probable better ways to achieve this. It uses the jQuery Context menu Library Located Here
I enjoyed creating it and though that you guys might have some use out of it.
Here is the fiddle. I hope that it can hopefully help someone out there.
$(function() {
function createSomeMenu() {
var all_array = '{';
var x = event.clientX,
y = event.clientY,
elementMouseIsOver = document.elementFromPoint(x, y);
if (elementMouseIsOver.closest('a')) {
all_array += '"Link-Fold": {"name": "Link", "icon": "fa-external-link", "items": {"fold2-key1": {"name": "Open Site in New Tab"}, "fold2-key2": {"name": "Open Site in Split Tab"}, "fold2-key3": {"name": "Copy URL"}}},';
}
if (elementMouseIsOver.closest('img')) {
all_array += '"Image-Fold": {"name": "Image","icon": "fa-picture-o","items": {"fold1-key1": {"name":"Download Image"},"fold1-key2": {"name": "Copy Image Location"},"fold1-key3": {"name": "Go To Image"}}},';
}
all_array += '"copy": {"name": "Copy","icon": "copy"},"paste": {"name": "Paste","icon": "paste"},"edit": {"name": "Edit HTML","icon": "fa-code"}}';
return JSON.parse(all_array);
}
// setup context menu
$.contextMenu({
selector: 'body',
build: function($trigger, e) {
return {
callback: function(key, options) {
var m = "clicked: " + key;
console.log(m);
},
items: createSomeMenu()
};
}
});
});
Simple One
Note: dont use display:none instead use opacity to hide and show
var menu= document.querySelector('.context_menu');
document.addEventListener("contextmenu", function(e) {
e.preventDefault();
menu.style.position = 'absolute';
menu.style.left = e.pageX + 'px';
menu.style.top = e.pageY + 'px';
menu.style.opacity = 1;
});
document.addEventListener("click", function(e){
if(e.target.closest('.context_menu'))
return;
menu.style.opacity = 0;
});
.context_menu{
width:70px;
background:lightgrey;
padding:5px;
opacity :0;
}
.context_menu div{
margin:5px;
background:grey;
}
.context_menu div:hover{
margin:5px;
background:red;
cursor:pointer;
}
<div class="context_menu">
<div>menu 1</div>
<div>menu 2</div>
</div>
extra css
var menu= document.querySelector('.context_menu');
document.addEventListener("contextmenu", function(e) {
e.preventDefault();
menu.style.position = 'absolute';
menu.style.left = e.pageX + 'px';
menu.style.top = e.pageY + 'px';
menu.style.opacity = 1;
});
document.addEventListener("click", function(e){
if(e.target.closest('.context_menu'))
return;
menu.style.opacity = 0;
});
.context_menu{
width:120px;
background:white;
border:1px solid lightgrey;
opacity :0;
}
.context_menu div{
padding:5px;
padding-left:15px;
margin:5px 2px;
border-bottom:1px solid lightgrey;
}
.context_menu div:last-child {
border:none;
}
.context_menu div:hover{
background:lightgrey;
cursor:pointer;
}
<div class="context_menu">
<div>menu 1</div>
<div>menu 2</div>
<div>menu 3</div>
<div>menu 4</div>
</div>
I have a nice and easy implementation using Bootstrap as follows.
<select class="custom-select" id="list" multiple></select>
<div class="dropdown-menu" id="menu-right-click" style=>
<h6 class="dropdown-header">Actions</h6>
<a class="dropdown-item" href="" onclick="option1();">Option 1</a>
<a class="dropdown-item" href="" onclick="option2();">Option 2</a>
</div>
<script>
$("#menu-right-click").hide();
$(document).on("contextmenu", "#list", function (e) {
$("#menu-right-click")
.css({
position: 'absolute',
left: e.pageX,
top: e.pageY,
display: 'block'
})
return false;
});
function option1() {
// something you want...
$("#menu-right-click").hide();
}
function option2() {
// something else
$("#menu-right-click").hide();
}
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With