javascript - evento - Haciendo menús personalizados con el botón derecho del mouse para mi aplicación web




evento click derecho javascript (5)

Tengo algunos sitios web como google-docs y map-quest que tienen menús desplegables personalizados cuando haces clic derecho. De alguna manera, anulan el comportamiento del navegador del menú desplegable, y ahora estoy seguro de cómo lo hacen. Encontré un plugin jQuery que hace esto, pero aún tengo curiosidad por algunas cosas:

  • ¿Como funciona esto? ¿Se está anulando el menú desplegable del navegador o se simuló el efecto? ¿Si es así, cómo?
  • ¿Qué abstrae el complemento? ¿Qué está pasando detrás de escena?
  • ¿Es esta la única forma de lograr este efecto?

Vea varios menús contextuales personalizados en acción


Como dijo Adrian, los complementos funcionarán de la misma manera. Hay tres partes básicas que vas a necesitar:

1: Manejador de eventos para 'contextmenu' evento 'contextmenu' :

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

Aquí, puede vincular el controlador de eventos a cualquier selector para el que desee mostrar un menú. Elegí el documento completo.

2: controlador de eventos para 'click' evento 'click' (para cerrar el menú personalizado):

$(document).bind("click", function(event) {
    $("div.custom-menu").hide();
});

3: CSS para controlar la posición del menú:

.custom-menu {
    z-index:1000;
    position: absolute;
    background-color:#C0C0C0;
    border: 1px solid black;
    padding: 2px;
}

Lo importante con CSS es incluir el z-index y la position: absolute

No sería demasiado difícil envolver todo esto en un hábil plugin jQuery.

Puede ver una demostración simple aquí: http://jsfiddle.net/andrewwhitaker/fELma/


El menú de contexto del navegador está siendo anulado. No hay forma de aumentar el menú contextual nativo en ningún navegador importante.

Como el complemento está creando su propio menú, la única parte que realmente se está abstrayendo es el evento del menú contextual del navegador. El complemento crea un menú html basado en su configuración, luego coloca ese contenido en la ubicación de su clic.

Sí, esta es la única forma de crear un menú contextual personalizado. Obviamente, los diferentes complementos hacen las cosas un poco diferentes, pero todos anularán el evento del navegador y colocarán su propio menú basado en html en el lugar correcto.


Sé que esta pregunta es muy antigua, pero me ocurrió el mismo problema y lo resolví yo mismo, así que estoy respondiendo por si alguien encuentra esto en Google como lo hice yo. Basé mi solución en la de @ Andrew, pero básicamente modifiqué todo después.

EDITAR : viendo lo popular que ha sido últimamente, decidí actualizar también los estilos para que se vea más como 2014 y menos como Windows 95. Solucioné los errores @Quantico y @Trengot detectados, por lo que ahora es una respuesta más sólida.

EDIT 2 : Lo configuré con StackSnippets ya que son una nueva característica realmente genial. Dejo la buena jsfiddle aquí como referencia (haga clic en el 4º panel para ver cómo funcionan).

Nuevo fragmento de pila:

// 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  -->
Right click me

Nota: es posible que vea algunos pequeños errores (menú desplegable lejos del cursor, etc.), asegúrese de que funciona en jsfiddle , ya que es más similar a su página web que StackSnippets.


Sé que esto también es bastante viejo. Hace poco tuve la necesidad de crear un menú contextual que inserte en otros sitios que tienen diferentes propiedades en función del elemento al que se hace clic.

Es bastante duro, y hay formas probables de lograr esto. Utiliza el menú de contexto de jQuery Biblioteca ubicada aquí

Disfruté crearlo y aunque ustedes podrían sacarle provecho.

Aquí está el fiddle . Espero que pueda ayudar a alguien allá afuera.

$(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()
      };
    }
  });
});

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





right-click