我想向我的 Web 应用程序添加自定义右键单击菜单。这可以在不使用任何预建库的情况下完成吗?如果是这样,如何显示不使用 3rd 方 JavaScript 库的简单自定义右键单击菜单?
我的目标是类似于 Google Docs 的功能。它允许用户右键单击并向用户显示他们自己的菜单。
注意: 我想学习如何制作我自己的东西而不是使用别人已经制作的东西,因为大多数时候,那些 3rd 方库的功能很臃肿,而我只想要我需要的功能,所以我希望它完全手工制作我。
我想向我的 Web 应用程序添加自定义右键单击菜单。这可以在不使用任何预建库的情况下完成吗?如果是这样,如何显示不使用 3rd 方 JavaScript 库的简单自定义右键单击菜单?
我的目标是类似于 Google Docs 的功能。它允许用户右键单击并向用户显示他们自己的菜单。
注意: 我想学习如何制作我自己的东西而不是使用别人已经制作的东西,因为大多数时候,那些 3rd 方库的功能很臃肿,而我只想要我需要的功能,所以我希望它完全手工制作我。
回答您的问题 - 使用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>
但是您应该问问自己,您是否真的想覆盖默认的右键单击行为 - 这取决于您正在开发的应用程序。
对我非常有用。为了像我这样的人,期待菜单的绘制,我把我用来制作右键菜单的代码放在这里:
$(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>
一些漂亮的 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的只是在这个例子中,我个人将其删除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%;}
用于从右翼扩大到左边的菜单。您需要在某处添加边距或其他内容
根据此处和其他“流程”中的答案,我制作了一个看起来像 Google Chrome 的版本,带有 css3 过渡。 JS Fiddle
让我们开始吧,因为我们在这个页面上有上面的js,我们可以担心css和布局。我们将使用的布局是一个<a>
元素,带有一个<img>
元素或字体很棒的图标 ( <i class="fa fa-flag"></i>
) 和 a<span>
来显示键盘快捷键。所以这是结构:
<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.clientX
和e.clientY
。我们正在使用客户端,因此必须修复菜单 div。
var i = document.getElementById("menu").style;
if (document.addEventListener) {
document.addEventListener('contextmenu', function(e) {
var posX = e.clientX;
var posY = e.client[...]
就是这样!只需添加 css 过渡以淡入淡出,就完成了!
您可以尝试通过将以下内容添加到您的正文标签来简单地阻止上下文菜单:
<body oncontextmenu="return false;">
这将阻止对上下文菜单的所有访问(不仅从鼠标右键,而且从键盘)。
PS,您可以将此添加到要禁用上下文菜单的任何标签
例如:
<div class="mydiv" oncontextmenu="return false;">
将仅禁用该特定 div 中的上下文菜单