如何在网页中添加自定义右键菜单?

415
我想在我的网络应用程序中添加一个自定义右键菜单。是否可以在不使用任何预制库的情况下完成?如果可以,如何显示一个简单的自定义右键菜单,而不使用第三方JavaScript库?
我希望实现类似于Google文档的功能。它允许用户右键单击并显示他们自己的菜单。
注意:我想学习如何制作自己的自定义右键菜单,而不是使用别人已经制作好的东西,因为大多数时候,这些第三方库都有很多功能,而我只需要我需要的功能,所以我想完全手工制作。

5
刚刚偶然发现了这个网站:http://davidwalsh.name/html5-context-menu,喜欢HTML5。 - Nijboer IT
5
这绝对不是重复的问题。因为这个问题要求没有第三方库的答案,而另一个问题很可能使用Jquery *(我想写一个用户脚本中类似于Google驱动器的上下文菜单的上下文)*。 - user2284570
1
今天我找到了两个关于这个问题的好例子(我认为):DEMO 1 // DEMO 2(这个演示需要 jquery UI)。希望对大家有所帮助,再见。 - Drako
3
只是想指出,HTML5上下文菜单只在某些Firefox版本中受支持,据我所知其他浏览器都不支持。Chrome自版本61起就不再支持它。 - Dan Willett
4
针对使用React的人 - native-menu 复制了 所有 现有功能(复制、在新标签页中打开、在Google上搜索等),同时外观看起来更符合本地化(根据浏览器应用不同的样式)。演示 - Sam Denty
22个回答

321

回答你的问题 - 使用 contextmenu 事件, 如下所示:

if (document.addEventListener) {
  document.addEventListener('contextmenu', function(e) {
    alert("You've tried to open context menu"); //here you draw your own menu
    e.preventDefault();
  }, false);
} else {
  document.attachEvent('oncontextmenu', function() {
    alert("You've tried to open context menu");
    window.event.returnValue = false;
  });
}
<body>
  Lorem ipsum...
</body>

但你应该问问自己,你真的想要覆盖默认的右键行为吗 - 这取决于你正在开发的应用程序。


JSFIDDLE


19
经测试,适用于Opera 11.01,Firefox 3.6.13,Chrome 9,Safari 5(所有4个通过addEventListener)和IE 8(attachEvent)。 - Radek Benkel
114
你刚刚解释了如何禁用右键菜单。那么怎样创建我们自己的菜单呢? - Shashwat
24
你需要知道用户点击的位置,但你没有原始菜单。在那个位置创建一个容器,并在其中显示你的菜单。 - Radek Benkel
4
当您查看代码时,您会看到这一行e.preventDefault();。这就是为什么常规菜单没有显示的原因。您可以创建一些条件逻辑进行检查,如果在右键单击时按下了按键并且不调用e.preventDefault() - 那么您将获得常规浏览器菜单。 - Radek Benkel
6
"但你应该问自己,你真的想要覆盖默认的右键点击行为吗?"这种解决方案与@MohamedIqzas在下面答案中提供的实现有一个重要区别(https://dev59.com/-2445IYBdhLWcg3wWI6L#16481062)。在下面的回答中,只有特定的HTML元素会被禁止出现默认的上下文菜单,而不是整个文档。这使它变得不那么侵入性。 - Alex Fainshtein
显示剩余6条评论

93

这对我非常有用。为了像我这样的人,期望绘制菜单,我在这里放置我用来创建右键菜单的代码:

$(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;
  }
}
.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;
}
<!-- jQuery should be at least version 1.7 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="contextmenu.js"></script>
<link rel="stylesheet" href="contextmenu.css" />


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


8
为了让 mouseY(event)mouseX(event) 像预期的那样工作,需要在它们后面添加 px。示例链接:http://jsfiddle.net/a6w7n64o/。 - zanetu
1
@Adelphia - 任何非本地和非自己创建的内容都是第三方。jQuery实际上并没有太多额外的东西,不会拖慢任何速度。它非常有用,这个答案中使用的相同jQuery可以轻松转换为标准的JavaScript命令。它可能不完全符合原始问题的要求,但绝对是95%符合要求的。 - The Duke Of Marshall שלום
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - I wrestled a bear once.
6
在Firefox 39中,自定义菜单呈现后默认上下文菜单仍会显示在其上方。此外,自定义菜单在显示后立即消失。 - Matt
1
@Matt 我在Firefox 58中也遇到了同样的问题。这篇文章描述了一个解决方案,对我有效:https://dev59.com/snHYa4cB1Zd3GeqPPLwL#40545465 你需要禁用文档的事件传播,并在窗口对象上注册你的上下文菜单处理程序。这是一个调整后的fiddle: https://jsfiddle.net/jjgkLe3g/1/ - Nils-o-mat

50

一些漂亮的CSS和一些非标准的HTML标签,不使用外部库,可以 获得很好的效果(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>

注意:menu标签并不存在,这是我虚构的(你可以使用任何标签)

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

JavaScript只是这个例子中使用的,我个人会在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);

注意,您可以通过潜在地修改menu > menu{left:100%;}menu > menu{right:100%;}来创建一个从右到左展开的菜单。不过您需要在某处添加一些边距或其他东西。


2
你可能想在处理“contextmenu”事件的函数末尾添加return false;以支持更多的浏览器版本。 - stackprotector
如果我的意图是让菜单项显示一个弹出窗口并跳转到一个URL,那么将菜单项HTML标签包装在<a>标签中是否是实现这一目的的方法?还是编写JS代码以在单击时触发弹出窗口更为常见?很好的例子。这正是我所寻找的:从基本构建块构建的上下文菜单。即使我最终使用库,我认为这非常有用,因为我从中获得了理解。 - Philippe Carphin
@PhilippeCarphin 你可以使用任何标签。锚点标签可能更有意义。此外,menu[title]:before 是将标题注入标签的魔法,因此您不必使用它,可以根据需要在标签中填写内容。 - Isaac

42
根据这里和其他页面的回答,我制作了一个看起来像Google Chrome的版本,并使用了css3过渡效果。 JS Fiddle 让我们从简单的开始,因为我们在这个页面上已经有了上面的js代码,我们可以先关注CSS和布局。我们将使用一个包含图像元素或font awesome图标(<i class="fa fa-flag"></i>) 以及一个用于显示快捷键的 <span> 元素的 <a> 元素来构建布局。因此,结构如下:
<a href="#" onclick="doSomething()">
  <img src="path/to/image.gif" />
  This is a menu option
  <span>Ctrl + K</span>
</a>

我们将把它们放在一个div中,并在右键单击时显示该div。让我们像Google Chrome一样对其进行样式设置,好吗?

#menu a {
  display: block;
  color: #555;
  text-decoration: no[...]

现在我们将添加来自已接受答案的代码,并获取鼠标指针的X和Y值。为此,我们将使用e.clientXe.clientY。我们正在使用client,因此菜单div必须是fixed。

var i = document.getElementById("menu").style;
if (document.addEventListener) {
  document.addEventListener('contextmenu', function(e) {
    var posX = e.clientX;
    var posY = e.client[...]

And that is it! Just add the css transisions to fade in and out, and done!

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>


2
这个真是帮了我大忙!如果楼主想要一个简单的方法来应用于整个网页而不仅仅是一个 div,那么这个答案应该被接受 :) - Woody
3
当您右键单击页面的右侧时,菜单的某些部分会隐藏。 - Green
@Stephan Stanisic,你能指导我如何添加子菜单吗?我喜欢这个片段,它非常出色,对我来说运行得很好。谢谢。 - Lyn Robert
我使用了https://uranus.codingneko.repl.co的示例来创建一个上下文菜单。 - RixTheTyrunt

30

简单的启动函数,在光标位置创建一个上下文菜单,在鼠标离开时销毁它自己。

oncontextmenu = (e) => {
  e.preventDefault()
  let menu = document.createElement("div")
  menu.id = "ctxmenu"
  menu.style = `top:${e.pageY-10}px;left:${e.pageX-40}px`
  menu.onmouseleave = () => ctxmenu.outerHTML = ''
  menu.innerHTML = "<p>Option1</p><p>Option2</p><p>Option3</p><p>Option4</p><p onclick='alert(`Thank you!`)'>Upvote</p>"
  document.body.appendChild(menu)
}
#ctxmenu {
  position: fixed;
  background: ghostwhite;
  color: black;
  cursor: pointer;
  border: 1px black solid
}

#ctxmenu > p {
  padding: 0 1rem;
  margin: 0
}

#ctxmenu > p:hover {
  background: black;
  color: ghostwhite
}


2
这是一个不错的解决方案,但如果你双击它会有问题! - Murat Kezli
是的,这很简单。为了避免您所提到的问题,我们可能需要测试具有id“ctxmenu”的元素是否已存在于DOM中。按照同样的逻辑,我们应该使用一个带有布尔值的变量,例如isDisplayed = true/false,而不是解析。 - NVRM
在这种情况下,正确的代码应该像这样 ;)oncontextmenu = (e) => { const ctxmenudiv = document.getElementById('ctxmenu'); if (ctxmenudiv === null) { e.preventDefault(); const menu = document.createElement("div"); menu.id = "ctxmenu" menu.style = top:${e.pageY-10}px;left:${e.pageX-40}px menu.onmouseleave = () => ctxmenu.outerHTML = '' menu.innerHTML = "<p>选项1</p><p>选项2</p><p>选项3</p><p>选项4</p><p onclick='alert(`谢谢!`)'>点赞</p>" document.body.appendChild(menu); } } - Murat Kezli
1
越少越好,最佳答案 - MertHaddad
1
简洁明了,解决问题,不炫耀的样式。谢谢! - Jordan

15

这是一个纯JS和CSS解决方案,用于创建一个真正动态的右键菜单。它基于预定义的元素ID、链接等命名约定。

jsfiddle

你可以将其复制粘贴到一个静态HTML页面中:

var rgtClickContextMenu = document.getElementById('div-context-menu');

/** close the right click context menu on click anywhere else in the page*/
document.onclick = function(e) {
  rgtClickContextMenu.style.display = 'none';
}

/**
 present the right click context menu ONLY for the elements having the right class
 by replacing the 0 or any digit after the "to-" string with the element id , which
 triggered the event
*/
document.oncontextmenu = function(e) {
  //alert(e.target.id)
  var elmnt = e.target
  if (elmnt.className.startsWith("cls-context-menu")) {
    e.preventDefault();
    var eid = elmnt.id.replace(/link-/, "")
    rgtClickContextMenu.style.left = e.pageX + 'px'
    rgtClickContextMenu.style.top = e.pageY + 'px'
    rgtClickContextMenu.style.display = 'block'
    var toRepl = "to=" + eid.toString()
    rgtClickContextMenu.innerHTML = rgtClickContextMenu.innerHTML.replace(/to=\d+/g, toRepl)
    //alert(rgtClickContextMenu.innerHTML.toString())
  }
}
.cls-context-menu-link {
  display: block;
  padding: 20px;
  background: #ECECEC;
}

.cls-context-menu {
  position: absolute;
  display: none;
}

.cls-context-menu ul,
#context-menu li {
  list-style: none;
  margin: 0;
  padding: 0;
  background: white;
}

.cls-context-menu {
  border: solid 1px #CCC;
}

.cls-context-menu li {
  border-bottom: solid 1px #CCC;
}

.cls-context-menu li:last-child {
  border: none;
}

.cls-context-menu li a {
  display: block;
  padding: 5px 10px;
  text-decoration: none;
  color: blue;
}

.cls-context-menu li a:hover {
  background: blue;
  color: #FFF;
}
<!-- those are the links which should present the dynamic context menu -->
<a id="link-1" href="#" class="cls-context-menu-link">right click link-01</a>
<a id="link-2" href="#" class="cls-context-menu-link">right click link-02</a>

<!-- this is the context menu -->
<!-- note the string to=0 where the 0 is the digit to be replaced -->
<div id="div-context-menu" class="cls-context-menu">
  <ul>
    <li><a href="#to=0">link-to=0 -item-1 </a></li>
    <li><a href="#to=0">link-to=0 -item-2 </a></li>
    <li><a href="#to=0">link-to=0 -item-3 </a></li>
  </ul>
</div>


这更接近我期望的答案,一个实际修改右键菜单的例子。 - Jesse Reza Khorasanee
是的,一个类似的例子可以是:codepen.io/yordangeorgiev/pen/GzWJzd,最终产品:https://qto.fi/qto/view/concepts_doc(只需点击登录...) - Yordan Georgiev

14

您可以尝试通过将以下代码添加到 body 标签来简单地阻止上下文菜单:

```html oncontextmenu="return false;" ```

<body oncontextmenu="return false;">

这将阻止所有对上下文菜单的访问(不仅是通过鼠标右键,还包括通过键盘)。

P.S. 您可以将此添加到任何标签中以禁用上下文菜单

例如:

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

将仅禁用特定div中的上下文菜单


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

已在Opera 11.6、Firefox 9.01、Internet Explorer 9和Chrome 17中进行了测试并且能够正常工作。


它能用,但你网页上的演示菜单真的很小而拥挤。不过是个好例子。 - David Millar
2
如果您使用的是三键鼠标,它可以正常工作。Ctrl + 单击则无法实现。@Singles提供了更好的建议,即使有些需要想象力。 - AJFarkas

9

试试这个:

var cls = true;
var ops;

window.onload = function() {
    document.querySelector(".container").addEventListener("mouseenter", function() {
        cls = false;
    });
    document.querySelector(".container").addEventListener("mouseleave", function() {
        cls = true;
    });
    ops = document.querySelectorAll(".container td");
    for (let i = 0; i < ops.length; i++) {
        ops[i].addEventListener("click", function() {
            document.querySelector(".position").style.display = "none";
        });
    }

    ops[0].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 1!");
        }, 50);
    });

    ops[1].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 2!");
        }, 50);
    });

    ops[2].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 3!");
        }, 50);
    });

    ops[3].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 4!");
        }, 50);
    });

    ops[4].addEventListener("click", function() {
        setTimeout(function() {
            /* YOUR FUNCTION */
            alert("Alert 5!");
        }, 50);
    });
}

document.addEventListener("contextmenu", function() {
    var e = window.event;
    e.preventDefault();
    document.querySelector(".container").style.padding = "0px";

    var x = e.clientX;
    var y = e.clientY;

    var docX = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || document.body.offsetWidth;
    var docY = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight || document.body.offsetHeight;

    var border = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('border-width'));

    var objX = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('width')) + 2;
    var objY = parseInt(getComputedStyle(document.querySelector(".container"), null).getPropertyValue('height')) + 2;

    if (x + objX > docX) {
        let diff = (x + objX) - docX;
        x -= diff + border;
    }

    if (y + objY > docY) {
        let diff = (y + objY) - docY;
        y -= diff + border;
    }

    document.querySelector(".position").style.display = "block";

    document.querySelector(".position").style.top = y + "px";
    document.querySelector(".position").style.left = x + "px";
});

window.addEventListener("resize", function() {
    document.querySelector(".position").style.display = "none";
});

document.addEventListener("click", function() {
    if (cls) {
        document.querySelector(".position").style.display = "none";
    }
});

document.addEventListener("wheel", function() {
    if (cls) {
        document.querySelector(".position").style.display = "none";
        static = false;
    }
});
.position {
    position: absolute;
    width: 1px;
    height: 1px;
    z-index: 2;
    display: none;
}

.container {
    width: 220px;
    height: auto;
    border: 1px solid black;
    background: rgb(245, 243, 243);
}

.container p {
    height: 30px;
    font-size: 18px;
    font-family: arial;
    width: 99%;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgb(245, 243, 243);
    color: black;
    transition: 0.2s;
}

.container p:hover {
    background: lightblue;
}

td {
    font-family: arial;
    font-size: 20px;
}

td:hover {
    background: lightblue;
    transition: 0.2s;
    cursor: pointer;
}
<div class="position">
    <div class="container" align="center">
        <table style="text-align: left; width: 99%; margin-left: auto; margin-right: auto;" border="0" cellpadding="2" cellspacing="2">
            <tbody>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 1<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 2<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 3<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 4<br>
                    </td>
                </tr>
                <tr>
                    <td style="vertical-align: middle; text-align: center;">Option 5<br>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>


4
我觉得这是最好的答案,因为它展示了一个实际的代码片段,在你选择不同选项时可以看到动作发生。赞一个! - user14550434

7

这里有一个非常好的 自定义右键菜单教程,附带完整的工作代码示例(不需要 JQuery 或其他库)。

你也可以在他们的 GitHub 上找到演示代码

他们提供了详细的逐步说明,让你可以跟着构建自己的右键菜单(包括 html、css 和 javascript 代码),并在最后通过给出完整的示例代码进行总结。

你可以轻松地跟着操作,并根据自己的需求进行调整。而且没有必要使用 JQuery 或其他库。

这是他们示例菜单代码的样子:

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

在 codepen 上可以找到一个工作示例(任务列表)


一个简短的摘要可以帮助审阅者(比如我)判断你的答案是否有效,并且可能会让一些读者不必跟随那个链接。只需要一两句话就可以了,不会太费力。 - Ingo Karkat
@IngoKarkat 谢谢您的建议。我添加了一些解释。希望您会发现这很有帮助。它对我非常有帮助。 - ForceOfWill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接