我想添加一个自定义右键菜单到我的web应用程序。这可以在不使用任何预先构建的库的情况下完成吗?如果是这样,如何显示一个简单的自定义右键菜单,不使用第三方JavaScript库?

我的目标是像谷歌Docs做的东西。它允许用户右键单击并显示用户自己的菜单。

注意: 我想学习如何制作我自己的,而不是使用别人已经制作的东西,因为大多数时候,那些第三方库的功能都很臃肿,而我只想要我需要的功能,所以我希望它完全由我手工制作。


回答你的问题-使用上下文菜单事件,如下所示:

if (document.addEventListener) { 文档。addEventListener('contextmenu',函数(e) { alert(“您已尝试打开上下文菜单”);//在这里您可以绘制自己的菜单 e.preventDefault (); },假); }其他{ 文档。attachEvent('oncontextmenu', function() { alert(“您已尝试打开上下文菜单”); window.event.returnValue = false; }); } <身体> Lorem ipsum…… < /身体>

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


吉斯菲德尔


<!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中运行 你可以在javascript右键菜单中查看工作示例


对我很有用。为了让像我这样的人,期待绘制菜单,我把我用来制作右键菜单的代码放在这里:

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


你可以试着通过在body标签中添加以下内容来阻止上下文菜单:

<body oncontextmenu="return false;">

这将阻止对上下文菜单的所有访问(不仅从鼠标右键,而且从键盘)。

附注:你可以把它添加到任何你想禁用上下文菜单的标签上

例如:

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

将禁用上下文菜单在特定的div只


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

一个简单的方法是使用onContextMenu返回一个JavaScript函数:

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

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

7:13进入的时候,回的是虚假。您将取消上下文菜单。

如果你仍然想显示上下文菜单,你可以删除返回false;线。


已测试,可在Opera 12.17, firefox 30, Internet Explorer 9和chrome 26.0.1410.64中运行

document.oncontextmenu =function( evt ){
        alert("OK?");
        return false;
        }

你应该记住,如果你想使用Firefox唯一的解决方案,如果你想把它添加到整个文档,你应该把contextmenu="mymenu"添加到<html>标签,而不是body标签。 你应该注意这一点。


一些漂亮的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>

注意:菜单标签不存在,我是虚构的(你可以使用任何东西)

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只是为这个例子,我个人删除它在窗口上的持久菜单

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{left:100%;}修改为菜单> menu{right:100%;}。你需要在某个地方加上一个边距之类的东西


试试这个

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


你可以用这段代码来做。 访问这里获得完整的自动边缘检测教程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();
 });
 });

`


根据这里和其他'流程的答案,我已经制作了一个看起来像谷歌Chrome的版本,带有css3过渡。 JS小提琴

让我们开始简单,因为我们有上面的js在这个页面上,我们可以担心css和布局。我们将使用的布局是一个<a>元素和一个<img>元素或一个字体awesome图标(<i class="fa fa-flag"></i>)和一个<span>来显示键盘快捷键。这就是结构:

<a href="#" onclick="doSomething()">
  <img src="path/to/image.gif" />
  This is a menu option
  <span>Ctrl + K</span>
</a>

我们将把这些放在一个div中,并在右键菜单中显示该div。让我们风格他们像在谷歌Chrome浏览器,好吗?

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

现在,我们将从接受的答案中添加代码,并获得游标的X和Y值。为此,我们将使用e.clientX和e. clienti。我们正在使用客户端,所以菜单div必须被修复。

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>


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

您可以调整和修改这段代码,使上下文菜单看起来更美观、更高效。至于修改一个现有的上下文菜单,我不知道如何做到这一点…看看这把小提琴,有组织的观点。另外,试着点击我的上下文菜单中的项目。他们应该提醒你一些很棒的信息。如果它们不起作用,那就试试别的……复杂。


这是一个很好的教程,教你如何用一个完整的工作代码示例(不含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>

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


我知道这个问题已经有了答案,但我花了一些时间来解决第二个答案,以使本机上下文菜单消失,并在用户单击的地方显示出来。 超文本标记语言

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

CodePen例子


<script>
function fun(){
document.getElementById('menu').style.display="block";
}

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

<body oncontextmenu="fun();return false;">

我在这里做什么

创建自己的自定义div菜单,并设置位置:绝对和显示:none以防万一。 将oncontextmenu事件添加到要单击的页面或元素中。 使用返回false取消默认的浏览器操作。 使用js调用自己的操作。


我使用类似于下面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);
    });
}

如果你的目标浏览器是旧的IE浏览器,你应该用' attachEvent;情况下


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


最简单的跳跃开始函数,在光标位置创建一个上下文菜单,在鼠标离开时破坏自己。

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 }


试试这个:

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>


对于那些使用bootstrap 5和jQuery 3寻找一个非常简单的自定义上下文菜单的自包含实现的人来说,这里是…

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
    <title>Custom Context Menu</title>
</head>
<style>
#context-menu {
  position: absolute;
  display: none;
}
</style>
<body>
    <div class="container-fluid p-5">
        <div class="row p-5">
            <div class="col-4">
                <span id="some-element" class="border border-2 border-primary p-5">Some element</span>
            </div>
        </div>
        <div id="context-menu" class="dropdown clearfix">
            <ul class="dropdown-menu" style="display:block;position:static;margin-bottom:5px;">
              <li><a class="dropdown-item" href="#" data-value="copy">Copy</a></li>
              <li><hr class="dropdown-divider"></li>
              <li><a class="dropdown-item" href="#" data-value="select-all">Select All</a></li>
            </ul>
        </div>       
        <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
        <script>
            $('body').on('contextmenu', '#some-element', function(e) {
                $('#context-menu').css({
                    display: "block",
                    left: e.pageX,
                    top: e.pageY
                });
                return false;
            });
            $('html').click(function() {
                $('#context-menu').hide();
            });
            $("#context-menu li a").click(function(e){
                console.log('in context-menu item, value = ' + $(this).data('value'));
            });
        </script>
    </body>
</html>

改编自https://codepen.io/anirugu/pen/xjjxvG