javascript - ¿Cómo agregar un menú de clic derecho personalizado a una página web?
click derecho javascript (18)
Aquí hay un muy buen tutorial sobre cómo crear un menú de contexto personalizado con un ejemplo de código de trabajo completo (sin JQuery y otras bibliotecas).
También puede encontrar su código de demostración en GitHub .
Brindan una explicación detallada paso a paso que puede seguir para crear su propio menú contextual de clic con el botón derecho (incluido el código html, css y javascript) y resumirlo al final dando el código de ejemplo completo.
Puede seguirlo fácilmente y adaptarlo a sus propias necesidades. Y no hay necesidad de JQuery u otras bibliotecas.
Así es como se ve el código de menú de ejemplo:
$(document).ready(function () {
$("html").on("contextmenu",function(e){
//prevent default context menu for right click
e.preventDefault();
var menu = $(".menu");
//hide menu if already shown
menu.hide();
//get x and y values of the click event
var pageX = e.pageX;
var pageY = e.pageY;
//position menu div near mouse cliked area
menu.css({top: pageY , left: pageX});
var mwidth = menu.width();
var mheight = menu.height();
var screenWidth = $(window).width();
var screenHeight = $(window).height();
//if window is scrolled
var scrTop = $(window).scrollTop();
//if the menu is close to right edge of the window
if(pageX+mwidth > screenWidth){
menu.css({left:pageX-mwidth});
}
//if the menu is close to bottom edge of the window
if(pageY+mheight > screenHeight+scrTop){
menu.css({top:pageY-mheight});
}
//finally show the menu
menu.show();
});
$("html").on("click", function(){
$(".menu").hide();
});
});
Un ejemplo de trabajo (lista de tareas) se puede encontrar en codepen .
Quiero agregar un menú de clic derecho personalizado a mi aplicación web. ¿Se puede hacer esto sin usar bibliotecas pre-construidas? De ser así, ¿cómo mostrar un menú de clic derecho personalizado que no utiliza una biblioteca de JavaScript de terceros?
Estoy apuntando a algo como lo que hace Google Docs. Permite a los usuarios hacer clic con el botón derecho y mostrar a los usuarios su propio menú.
NOTA: quiero aprender a hacer mi propio uso de algo que alguien ya hizo ya que la mayoría de las veces, esas bibliotecas de terceros están repletas de características, mientras que solo quiero las características que necesito, así que quiero que estén completamente hechas a mano por yo.
De acuerdo con las respuestas aquí y en otros flujos, he creado una versión que se parece a la de Google Chrome, con transición css3. JS Fiddle
Comencemos rápido, ya que tenemos el js arriba en esta página, podemos preocuparnos por el css y el diseño. El diseño que <a>
es un elemento <a>
con un elemento <img>
o un icono impresionante de fuente ( <i class="fa fa-flag"></i>
) y un <span>
para mostrar el teclado atajos Así que esta es la estructura:
<a href="#" onclick="doSomething()">
<img src="path/to/image.gif" />
This is a menu option
<span>Ctrl + K</span>
</a>
Pondremos estos en un div y mostraremos ese div en el clic derecho. Vamos a estilizarlas como en Google Chrome, ¿vale?
#menu a {
display: block;
color: #555;
text-decoration: no[...]
Ahora agregaremos el código de la respuesta aceptada y obtendremos los valores X e Y del cursor. Para hacer esto, usaremos e.clientX
y e.clientY
. Estamos usando cliente, por lo que el menú div tiene que ser arreglado.
var i = document.getElementById("menu").style;
if (document.addEventListener) {
document.addEventListener(''contextmenu'', function(e) {
var posX = e.clientX;
var posY = e.client[...]
¡Y eso es todo! Solo agrega las transiciones css para aparecer y desaparecer, ¡y listo!
var i = document.getElementById("menu").style;
if (document.addEventListener) {
document.addEventListener(''contextmenu'', function(e) {
var posX = e.clientX;
var posY = e.clientY;
menu(posX, posY);
e.preventDefault();
}, false);
document.addEventListener(''click'', function(e) {
i.opacity = "0";
setTimeout(function() {
i.visibility = "hidden";
}, 501);
}, false);
} else {
document.attachEvent(''oncontextmenu'', function(e) {
var posX = e.clientX;
var posY = e.clientY;
menu(posX, posY);
e.preventDefault();
});
document.attachEvent(''onclick'', function(e) {
i.opacity = "0";
setTimeout(function() {
i.visibility = "hidden";
}, 501);
});
}
function menu(x, y) {
i.top = y + "px";
i.left = x + "px";
i.visibility = "visible";
i.opacity = "1";
}
body {
background: white;
font-family: sans-serif;
color: #5e5e5e;
}
#menu {
visibility: hidden;
opacity: 0;
position: fixed;
background: #fff;
color: #555;
font-family: sans-serif;
font-size: 11px;
-webkit-transition: opacity .5s ease-in-out;
-moz-transition: opacity .5s ease-in-out;
-ms-transition: opacity .5s ease-in-out;
-o-transition: opacity .5s ease-in-out;
transition: opacity .5s ease-in-out;
-webkit-box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
-moz-box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
padding: 0px;
border: 1px solid #C6C6C6;
}
#menu a {
display: block;
color: #555;
text-decoration: none;
padding: 6px 8px 6px 30px;
width: 250px;
position: relative;
}
#menu a img,
#menu a i.fa {
height: 20px;
font-size: 17px;
width: 20px;
position: absolute;
left: 5px;
top: 2px;
}
#menu a span {
color: #BCB1B3;
float: right;
}
#menu a:hover {
color: #fff;
background: #3879D9;
}
#menu hr {
border: 1px solid #EBEBEB;
border-bottom: 0;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
<h2>CSS3 and JAVASCRIPT custom menu.</h2>
<em>Stephan Stanisic | Lisence free</em>
<p>Right-click anywhere on this page to open the custom menu. Styled like the Google Chrome contextmenu. And yes, you can use <i class="fa fa-flag"></i>font-awesome</p>
<p style="font-size: small">
<b>Lisence</b>
<br /> "THE PIZZA-WARE LICENSE" (Revision 42):
<br /> You can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a Pizza in return.
<br />
<a style="font-size:xx-small" href="https://github.com/KLVN/UrbanDictionary_API#license">https://github.com/KLVN/UrbanDictionary_API#license</a>
</p>
<br />
<br />
<small>(The white body background is just because I hate the light blue editor background on the result on jsfiddle)</small>
<div id="menu">
<a href="#">
<img src="http://puu.sh/nr60s/42df867bf3.png" /> AdBlock Plus <span>Ctrl + ?!</span>
</a>
<a href="#">
<img src="http://puu.sh/nr5Z6/4360098fc1.png" /> SNTX <span>Ctrl + ?!</span>
</a>
<hr />
<a href="#">
<i class="fa fa-fort-awesome"></i> Fort Awesome <span>Ctrl + ?!</span>
</a>
<a href="#">
<i class="fa fa-flag"></i> Font Awesome <span>Ctrl + ?!</span>
</a>
</div>
Debe recordar que si desea usar la única solución de Firefox, si desea agregarla a todo el documento, debe agregar contextmenu="mymenu"
a la etiqueta <html>
no a la etiqueta del body
.
Debes prestar atención a esto.
En el nuevo html 5.1, hay una nueva característica de menús de contexto.
IMPORTANT: ATM, This feature works only in Firefox 49 and later.
Fue muy útil para mí. Por el bien de personas como yo, esperando el dibujo del menú, pongo aquí el código que usé para hacer el menú del botón derecho:
HTML : contextmenu.html
<!doctype html>
<html>
<head>
<!-- jQuery should be at least version 1.7 -->
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="contextmenu.js"></script>
<link rel="stylesheet" href="contextmenu.css" />
</head>
<body>
<div id="test1">
<a href="www.google.com" class="test">Google</a>
<a href="www.google.com" class="test">Link 2</a>
<a href="www.google.com" class="test">Link 3</a>
<a href="www.google.com" class="test">Link 4</a>
</div>
<!-- initially hidden right-click menu -->
<div class="hide" id="rmenu">
<ul>
<li>
<a href="http://www.google.com">Google</a>
</li>
<li>
<a href="http://localhost:8080/login">Localhost</a>
</li>
<li>
<a href="C:/">C</a>
</li>
</ul>
</div>
</body>
</html>
CSS: contextmenu.css
.show {
z-index:1000;
position: absolute;
background-color:#C0C0C0;
border: 1px solid blue;
padding: 2px;
display: block;
margin: 0;
list-style-type: none;
list-style: none;
}
.hide {
display: none;
}
.show li{ list-style: none; }
.show a { border: 0 !important; text-decoration: none; }
.show a:hover { text-decoration: underline !important; }
JS: contextmenu.js - usado de la respuesta aceptada
$(document).ready(function() {
if ($("#test").addEventListener) {
$("#test").addEventListener(''contextmenu'', function(e) {
alert("You''ve tried to open context menu"); //here you draw your own menu
e.preventDefault();
}, false);
} else {
//document.getElementById("test").attachEvent(''oncontextmenu'', function() {
//$(".test").bind(''contextmenu'', function() {
$(''body'').on(''contextmenu'', ''a.test'', function() {
//alert("contextmenu"+event);
document.getElementById("rmenu").className = "show";
document.getElementById("rmenu").style.top = mouseY(event) + ''px'';
document.getElementById("rmenu").style.left = mouseX(event) + ''px'';
window.event.returnValue = false;
});
}
});
// this is from another SO post...
$(document).bind("click", function(event) {
document.getElementById("rmenu").className = "hide";
});
function mouseX(evt) {
if (evt.pageX) {
return evt.pageX;
} else if (evt.clientX) {
return evt.clientX + (document.documentElement.scrollLeft ?
document.documentElement.scrollLeft :
document.body.scrollLeft);
} else {
return null;
}
}
function mouseY(evt) {
if (evt.pageY) {
return evt.pageY;
} else if (evt.clientY) {
return evt.clientY + (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop);
} else {
return null;
}
}
Probado y funciona en Opera 12.17, Firefox 30, Internet Explorer 9 y Chrome 26.0.1410.64
document.oncontextmenu =function( evt ){
alert("OK?");
return false;
}
Prueba esto
$(function() {
var doubleClicked = false;
$(document).on("contextmenu", function (e) {
if(doubleClicked == false) {
e.preventDefault(); // To prevent the default context menu.
var windowHeight = $(window).height()/2;
var windowWidth = $(window).width()/2;
if(e.clientY > windowHeight && e.clientX <= windowWidth) {
$("#contextMenuContainer").css("left", e.clientX);
$("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
$("#contextMenuContainer").css("right", "auto");
$("#contextMenuContainer").css("top", "auto");
} else if(e.clientY > windowHeight && e.clientX > windowWidth) {
$("#contextMenuContainer").css("right", $(window).width()-e.clientX);
$("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
$("#contextMenuContainer").css("left", "auto");
$("#contextMenuContainer").css("top", "auto");
} else if(e.clientY <= windowHeight && e.clientX <= windowWidth) {
$("#contextMenuContainer").css("left", e.clientX);
$("#contextMenuContainer").css("top", e.clientY);
$("#contextMenuContainer").css("right", "auto");
$("#contextMenuContainer").css("bottom", "auto");
} else {
$("#contextMenuContainer").css("right", $(window).width()-e.clientX);
$("#contextMenuContainer").css("top", e.clientY);
$("#contextMenuContainer").css("left", "auto");
$("#contextMenuContainer").css("bottom", "auto");
}
$("#contextMenuContainer").fadeIn(500, FocusContextOut());
doubleClicked = true;
} else {
e.preventDefault();
doubleClicked = false;
$("#contextMenuContainer").fadeOut(500);
}
});
function FocusContextOut() {
$(document).on("click", function () {
doubleClicked = false;
$("#contextMenuContainer").fadeOut(500);
$(document).off("click");
});
}
});
Puede intentar simplemente bloquear el menú contextual agregando lo siguiente a su etiqueta de cuerpo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<head>
<title>Context menu - LabLogic.net</title>
</head>
<body>
<script language="javascript" type="text/javascript">
document.oncontextmenu=RightMouseDown;
document.onmousedown = mouseDown;
function mouseDown(e) {
if (e.which==3) {//righClick
alert("Right-click menu goes here");
}
}
function RightMouseDown() { return false; }
</script>
</body>
</html>
Esto bloqueará todos los accesos al menú contextual (no solo desde el botón derecho del ratón, sino también desde el teclado).
PD: puede agregar esto a cualquier etiqueta en la que desee deshabilitar el menú contextual
por ejemplo:
<body oncontextmenu="return false;">
Deshabilitará el menú contextual en ese div en particular solamente
Puedes hacerlo con este código. Visite aquí para ver el tutorial completo con detección automática de bordes http://www.voidtricks.com/custom-right-click-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="View"><i class="fa fa-eye"></i> View Task</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Edit"><i class="fa fa-edit"></i> Edit Task</a>
</li>
<li class="context-menu__item">
<a href="#" class="context-menu__link" data-action="Delete"><i class="fa fa-times"></i> Delete Task</a>
</li>
</ul>
</nav>
`
Sé que esto ya ha sido respondido, pero pasé un tiempo luchando con la segunda respuesta para hacer que el menú contextual nativo desapareciera y mostrarlo donde el usuario hizo clic.
HTML
<body>
<div id="test1">
<a href="www.google.com" class="test">Google</a>
<a href="www.google.com" class="test">Link 2</a>
<a href="www.google.com" class="test">Link 3</a>
<a href="www.google.com" class="test">Link 4</a>
</div>
<!-- initially hidden right-click menu -->
<div class="hide" id="rmenu">
<ul>
<li class="White">White</li>
<li>Green</li>
<li>Yellow</li>
<li>Orange</li>
<li>Red</li>
<li>Blue</li>
</ul>
</div>
</body>
CSS
.hide {
display: none;
}
#rmenu {
border: 1px solid black;
background-color: white;
}
#rmenu ul {
padding: 0;
list-style: none;
}
#rmenu li
{
list-style: none;
padding-left: 5px;
padding-right: 5px;
}
JavaScript
if (document.getElementById(''test1'').addEventListener) {
document.getElementById(''test1'').addEventListener(''contextmenu'', function(e) {
$("#rmenu").toggleClass("hide");
$("#rmenu").css(
{
position: "absolute",
top: e.pageY,
left: e.pageX
}
);
e.preventDefault();
}, false);
}
// this is from another SO post...
$(document).bind("click", function(event) {
document.getElementById("rmenu").className = "hide";
});
Una combinación de algunos CSS agradables y algunas etiquetas html no estándar sin bibliotecas externas puede dar un buen resultado (JSFiddle)
HTML
<menu id="ctxMenu">
<menu title="File">
<menu title="Save"></menu>
<menu title="Save As"></menu>
<menu title="Open"></menu>
</menu>
<menu title="Edit">
<menu title="Cut"></menu>
<menu title="Copy"></menu>
<menu title="Paste"></menu>
</menu>
</menu>
Nota: la etiqueta de menú no existe, la estoy inventando (puedes usar cualquier cosa)
CSS
#ctxMenu{
display:none;
z-index:100;
}
menu {
position:absolute;
display:block;
left:0px;
top:0px;
height:20px;
width:20px;
padding:0;
margin:0;
border:1px solid;
background-color:white;
font-weight:normal;
white-space:nowrap;
}
menu:hover{
background-color:#eef;
font-weight:bold;
}
menu:hover > menu{
display:block;
}
menu > menu{
display:none;
position:relative;
top:-20px;
left:100%;
width:55px;
}
menu[title]:before{
content:attr(title);
}
menu:not([title]):before{
content:"/2630";
}
El JavaScript es solo para este ejemplo, lo elimino personalmente para los menús persistentes en Windows
var notepad = document.getElementById("notepad");
notepad.addEventListener("contextmenu",function(event){
event.preventDefault();
var ctxMenu = document.getElementById("ctxMenu");
ctxMenu.style.display = "block";
ctxMenu.style.left = (event.pageX - 10)+"px";
ctxMenu.style.top = (event.pageY - 10)+"px";
},false);
notepad.addEventListener("click",function(event){
var ctxMenu = document.getElementById("ctxMenu");
ctxMenu.style.display = "";
ctxMenu.style.left = "";
ctxMenu.style.top = "";
},false);
También tenga en cuenta que potencialmente puede modificar el menu > menu{left:100%;}
al menu > menu{right:100%;}
para un menú que se expande de derecha a izquierda. Necesitarías agregar un margen o algo en algún lugar aunque
Una forma sencilla de hacerlo es usar onContextMenu para devolver una función de JavaScript:
<input type="button" value="Example" onContextMenu="return RightClickFunction();">
<script>
function RightClickFunction() {
// Enter your code here;
return false;
}
</script>
Y al entrar return false;
cancelará el menú contextual.
Si aún desea visualizar el menú contextual, simplemente puede eliminar el return false;
línea.
Uso algo similar al siguiente jsfiddle
function onright(el, cb) {
//disable right click
document.body.oncontextmenu = ''return false'';
el.addEventListener(''contextmenu'', function (e) { e.preventDefault(); return false });
el.addEventListener(''mousedown'', function (e) {
e = e || window.event;
if (~~(e.button) === 2) {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
return false;
}
});
// then bind Your cb
el.addEventListener(''mousedown'', function (e) {
e = e || window.event;
~~(e.button) === 2 && cb.call(el, e);
});
}
Si apunta a navegadores IE más antiguos, debería completarla de todos modos con el ''attachEvent; caso
Respondiendo a su pregunta - use el evento de contextmenu
, como a continuación:
<html>
<head>
<script type="text/javascript">
if (document.addEventListener) { // IE >= 9; other browsers
document.addEventListener(''contextmenu'', function(e) {
alert("You''ve tried to open context menu"); //here you draw your own menu
e.preventDefault();
}, false);
} else { // IE < 9
document.attachEvent(''oncontextmenu'', function() {
alert("You''ve tried to open context menu");
window.event.returnValue = false;
});
}
</script>
</head>
<body>
Lorem ipsum...
</body>
</html>
Pero debe preguntarse si realmente desea sobrescribir el comportamiento predeterminado del botón derecho, depende de la aplicación que esté desarrollando.
<div class="mydiv" oncontextmenu="return false;">
Probado y funciona en Opera 11.6, Firefox 9.01, Internet Explorer 9 y Chrome 17 Puede ver una muestra de trabajo en el menú de clic derecho de JavaScript
<html>
<head>
<style>
.rightclick {
/* YOUR CONTEXTMENU''S CSS */
visibility: hidden;
background-color: white;
border: 1px solid grey;
width: 200px;
height: 300px;
}
</style>
</head>
<body>
<div class="rightclick" id="ya">
<p onclick="alert(''choc-a-late'')">I like chocolate</p><br><p onclick="awe-so-me">I AM AWESOME</p>
</div>
<p>Right click to get sweet results!</p>
</body>
<script>
document.onclick = noClick;
document.oncontextmenu = rightClick;
function rightClick(e) {
e = e || window.event;
e.preventDefault();
document.getElementById("ya").style.visibility = "visible";
console.log("Context Menu v1.3.0 by IamGuest opened.");
}
function noClick() {
document.getElementById("ya").style.visibility = "hidden";
console.log("Context Menu v1.3.0 by IamGuest closed.");
}
</script>
<!-- Coded by IamGuest. Thank you for using this code! -->
</html>
Puede modificar y modificar este código para crear un menú contextual más eficiente y con mejor aspecto. En cuanto a la modificación de un menú contextual existente, no estoy seguro de cómo hacerlo ... Echa un vistazo a este fiddle para un punto de vista organizado. Además, intente hacer clic en los elementos en mi menú contextual. Deben alertarte unos mensajes impresionantes. Si no funcionan, intente algo más ... complejo.
<script language="javascript" type="text/javascript">
document.oncontextmenu = RightMouseDown;
document.onmousedown = mouseDown;
function mouseDown(e) {
if (e.which==3) {//righClick
alert("Right-click menu goes here");
}
}
function RightMouseDown() {
return false;
}
</script>
</body>
</html>
<script>
function fun(){
document.getElementById(''menu'').style.display="block";
}
</script>
<div id="menu" style="display: none"> menu items</div>
<body oncontextmenu="fun();return false;">
Lo que estoy haciendo aquí
- Cree su propio menú div personalizado y establezca la posición: absoluta y visualización: ninguna en caso.
- Agregue a la página o elemento para hacer clic en el evento oncontextmenu.
- Cancele la acción del navegador por defecto con devolver falso.
Usuario js para invocar tus propias acciones.