javascript - menu click derecho jquery




¿Cómo agregar un menú de clic derecho personalizado a una página web? (12)

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.


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 .


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>


En el nuevo html 5.1, hay una nueva característica de menús de contexto.

Ejemplo aquí

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;
    }
}

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");           
 });
}
});

http://jsfiddle.net/AkshayBandivadekar/zakn7Lwb/14/


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


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";
});

Ejemplo de CodePen


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


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.

JSFIDDLE


<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>




right-click