Como adicionar um menu personalizado com o botão direito a uma página web?

quero adicionar um menu personalizado com o botão direito à minha aplicação web. Isto pode ser feito sem usar bibliotecas pré-construídas? Em caso afirmativo, como apresentar um menu personalizado com o botão direito que não utilize uma biblioteca de JavaScript de terceiros?

Estou a apontar para algo como o que o Google Docs faz. Permite ao Utilizador carregar com o botão direito e mostrar aos utilizadores o seu próprio menu.

nota: Quero aprender a fazer o meu contra usar algo que alguém já fez desde a maior parte do tempo., essas bibliotecas da terceira parte são inchadas com recursos, enquanto eu só quero recursos que eu preciso para que eu quero que ele seja completamente feito à mão por mim.

Author: Mogsdad, 2011-02-05

18 answers

Respondendo à sua pergunta-use contextmenu evento, como em baixo:

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

Mas você deve perguntar a si mesmo, você realmente quer sobrepor o comportamento padrão do botão direito-depende da aplicação que você está desenvolvendo.


JSFIDDLE

 217
Author: singles, 2016-10-01 11:42:31

Foi muito útil para mim. Para o bem de pessoas como eu, esperando o desenho do menu, coloquei aqui o código que usei para fazer o menu do botão direito:

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-utilizado a partir da resposta aceite

$(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;
    }
}
 38
Author: Mohamed Iqzas, 2015-03-13 03:51:31
<!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>

Testado e funciona no Opera 11.6, firefox 9.01, Internet Explorer 9 e chrome 17 Você pode verificar uma amostra de trabalho no javascript botão direito do menu

 10
Author: LabLogic, 2012-03-06 02:23:16

Pode tentar simplesmente bloquear o menu de contexto adicionando o seguinte à sua marca corporal:

<body oncontextmenu="return false;">

Isto irá bloquear todo o acesso ao menu de contexto (não apenas do botão direito do rato, mas também do teclado).

P. S. podes adicionar isto a qualquer marca que queiras desactivar o menu de contexto em

Por exemplo:

<div class="mydiv" oncontextmenu="return false;">

Irá desactivar o menu de contexto nesse div apenas

 10
Author: by0, 2013-06-07 15:27:34

Uma combinação de alguns bons CSS e algumas tags html não-padrão sem bibliotecas externas pode dar um bom 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: A etiqueta do menu não existe, estou a inventá-la (pode usar qualquer coisa) {[[9]}

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

O JavaScript é apenas para este exemplo, eu pessoalmente removo-o para menus persistentes no 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);

Também pode modificar menu > menu{left:100%;} para menu > menu{right:100%;} para um menu que se expande da direita para a esquerda. Você teria que adicionar uma margem ou algo em algum lugar embora

 10
Author: Isaac, 2015-05-24 01:43:37
De acordo com as respostas aqui e em outros fluxos, eu fiz uma versão que se parece com a do Google Chrome, com transição css3. Violino JS

Vamos começar eazy, já que temos o js acima nesta página, podemos nos preocupar com o css e layout. A disposição que vamos usar é um elemento <a> com um elemento <img> ou um ícone de tipo de letra impressionante (<i class="fa fa-flag"></i>) e um <span> para mostrar os atalhos de teclado. Então esta é a estrutura:

<a href="#" onclick="doSomething()">
  <img src="path/to/image.gif" />
  This is a menu option
  <span>Ctrl + K</span>
</a>
Nós vamos. põe isto num div e mostra o div no botão direito. Vamos pô-los como no Google Chrome, sim?
#menu a {
  display: block;
  color: #555;
  text-decoration: no[...]

Agora vamos adicionar o código da resposta aceite, e obter o valor X e Y do cursor. Para isso, usaremos e.clientX e e.clientY. Estamos a usar o cliente, por isso o menu div tem de ser corrigido.

var i = document.getElementById("menu").style;
if (document.addEventListener) {
  document.addEventListener('contextmenu', function(e) {
    var posX = e.clientX;
    var posY = e.client[...]
E é isso! Basta adicionar as transisões css para desaparecer dentro e fora, e pronto!
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>
 9
Author: Stephan Stanisic, 2016-03-01 18:26:33

Tenta Isto

$(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/

 5
Author: AkshayBandivadekar, 2015-08-07 07:20:25

Eu sei que isto já foi respondido, mas passei algum tempo a lutar com a segunda resposta para conseguir que o menu de contexto nativo desaparecesse e que aparecesse onde o utilizador clicou.
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";
});

Exemplo Do CodePen

 5
Author: Kristen Nielsen, 2016-11-10 19:32:37
Podes fazê-lo com este código. visite aqui para um tutorial completo com detecção automática de contornos http://www.voidtricks.com/custom-right-click-context-menu/
$(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();
 });
 });

`

 2
Author: Anand Roshan, 2015-10-20 15:44:25

Aqui está um tutorial muito bom sobre como construir um menu de contexto personalizado com um exemplo de código de trabalho completo (sem JQuery e outras bibliotecas).

Você também pode encontrar o seu código demo no GitHub .

Eles dão uma explicação detalhada passo-a-passo que você pode seguir para construir o seu próprio menu de contexto com o botão direito (incluindo html, CSS e código javascript) e resumi-lo no final, dando o código de exemplo completo.

Podes seguir-me facilmente. e adaptá-lo às suas próprias necessidades. E não há necessidade de JQuery ou outras bibliotecas.

É assim que o código do menu exemplo se parece:

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

Um exemplo de trabalho (lista de tarefas) pode ser encontrado no codepen.

 2
Author: ForceOfWill, 2016-10-04 08:07:01
<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>
 1
Author: Graham Allen, 2013-10-29 05:35:19

Uma forma simples de o fazer é usar o onContextMenu para devolver uma função JavaScript:

<input type="button" value="Example" onContextMenu="return RightClickFunction();">

<script>
 function RightClickFunction() {
  // Enter your code here;
  return false;
 }
</script>

E ao introduzir return false;, irá cancelar o menu de contexto.

Se ainda quiser mostrar o menu de contexto, basta remover a linha return false;.

 1
Author: EpicNinjaCheese, 2014-02-12 23:45:08

Tested and works in Opera 12.17, firefox 30, Internet Explorer 9 and chrome 26.0.1410.64

document.oncontextmenu =function( evt ){
        alert("OK?");
        return false;
        }
 1
Author: raphpell, 2014-06-22 10:17:43

Deve lembrar-se se quiser usar a solução só para o Firefox, se quiser adicioná-la a todo o documento deve adicionar {[[0]} à marca <html> e não à marca body.
Devias prestar atenção a isto.

 0
Author: WowOWwoW, 2014-10-10 17:50:17

No novo html 5.1, existe um novo menu de contexto.

Exemplo Aqui

IMPORTANT: ATM, This feature works only in Firefox 49 and later. 
 0
Author: Asaf Hananel, 2016-12-05 15:40:12
<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>
Pode ajustar e modificar este código para tornar um contextmenu mais atraente e eficiente. Quanto a modificar um contextmenu existente, não sei como fazer isso... Olha para isto. violino para um ponto de vista organizado. Além disso, tente clicar nos itens no meu contextmenu. Devem alertar-te para algumas mensagens fantásticas. Se não funcionarem, tenta algo mais... complexo.
 0
Author: IamGuest, 2017-02-23 08:26:49
<script>
function fun(){
document.getElementById('menu').style.display="block";
}

</script>
<div id="menu" style="display: none"> menu items</div>

<body oncontextmenu="fun();return false;">
O que estou a fazer aqui em cima
  1. Criar o seu próprio menu div personalizado e definir a posição: absoluto e mostrar:nenhum no caso.
  2. Adicione à página ou elemento para carregar no evento oncontextmenu.
  3. cancelar a acção predefinida do navegador com return false.
  4. O Utilizador js invoca as suas próprias acções.

 0
Author: Chris Enitan, 2017-07-26 12:08:10

Uso algo semelhante ao seguinte 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);
    });
}

Se escolher os navegadores IE mais antigos, deverá completá-lo de qualquer forma com o ' anexevent; case

 0
Author: fedeghe, 2018-07-04 19:26:59