如何在按钮或元素上隐藏自定义上下文菜单
How to hide a custom context menu when over a button or element
我正在寻找一种简单的方法来隐藏自定义上下文菜单,除非通过按钮或元素。这是我编写的一个简单示例,其中包含一个自定义上下文菜单和一个我希望将其附加到的按钮。我在想也许会有一个事件侦听器来寻找悬停在元素上的事件,或者可能有一个在需要时打开或关闭它的功能?另外我想知道按钮或元素是否没有用 class 或 ID 定义,是否仍然有办法知道你何时结束它,可能是通过坐标(如果可能的话,没必要只是好奇)?这个想法是会有多个元素需要上下文菜单,但是主体中元素周围的一般 space 不应显示自定义菜单。
function view() {
const contextMenu = document.getElementById('context-menu');
const scope = document.querySelector("body");
//body
var listLength = contextMenu.children.length;
for (i = 0; i < listLength; i++)
contextMenu.removeChild(contextMenu.children[0]);
contextMenuadd(contextMenu, "line 1 of context menu", 1);
contextMenuadd(contextMenu, "line 2 of context menu", 2);
contextMenuadd(contextMenu, "line 3 of context menu", 3);
contextMenuadd(contextMenu, "line 4 of context menu", 4);
scope.addEventListener("contextmenu", (event) => {
event.preventDefault();
const {
clientX: mouseX,
clientY: mouseY
} = event;
contextMenu.style.top = `${mouseY}px`;
contextMenu.style.left = `${mouseX}px`;
contextMenu.classList.add('visible');
contextMenu.style.display = 'block';
contextMenu.style.zIndex = 20000;
contextMenu.style.position = 'fixed';
contextMenu.style.width = "360px";
contextMenu.style.borderRadius = "5px";
});
scope.addEventListener("click", (e) => {
if (e.target.offsetParent != contextMenu) {
contextMenu.style.display = 'none';
}
});
};
document.addEventListener('DOMContentLoaded', view);
function contextMenuadd(contextMenu, menustring, count) {
var action = function(e) {
//menuLink;
let currentRow = $(event.target)[0].parentElement;
var index = parseInt(currentRow.row);
var value = currentRow.textContent;
en(href, '_self');
};
var menuitem = document.createElement('LI');
menuitem.addEventListener('click', action);
menuitem.classList.add("hotspot__item");
menuitem.innerHTML = '<a href="#">' + menustring + '</a>';
menuitem.row = count;
contextMenu.appendChild(menuitem);
};
document.addEventListener('click', function(e) {
let inside = (e.target.closest('#container'));
if (!inside) {
let contextMenu = document.getElementById('contextMenuId');
contextMenu.setAttribute('style', 'display:none');
}
});
#context-menu {
position: fixed;
z-index: 10000;
width: 180px;
background: #ffaaaa;
border-radius: 5px;
display: none;
}
#context-menu.item {
padding: 2px 4px;
font-size: 12px;
color: #eee;
cursor: pointer;
border-radius: inherit;
}
<body id="allofit">
<header>
<h2>Context Menu Example</h2>
</header>
<!-- <gm:figure-group> -->
<div id='sdi_canvas1' style="width:400px; height:400px">
<button id="container"> this is data in my DIV</button>
</div>
<div id="context-menu" class="context-menu"
oncontextmenu="ShowMenu('contextMenu',event)" style="display:none">
<div class="item">Option 1</div>
<div class="item">Option 2</div>
</div>
</body>
这里有一个fiddle供参考JSFiddle
您是否尝试过使用 'mouseover' 和 'mouseout' 事件?
如果这是您要找的,请告诉我:
const menu = document.querySelector('.menu')
const btn = document.getElementById('btn');
btn.addEventListener('mouseover', () => {
menu.style.display = "block";
});
btn.addEventListener('mouseout', () => {
menu.style.display = "none";
})
.menu {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<button id="btn">Hover me</button>
<ul class="menu">
<li>Test 1</li>
<li>Test 1</li>
</ul>
</body>
</html>
- 您可以向所有将显示自定义的元素添加 class
上下文菜单。
- 和
oncontextmenu
,您检查元素是否包含 class 然后相应地切换上下文菜单。
试试这个
document.addEventListener('DOMContentLoaded', () => {
const scope = document.querySelector("body");
const contextMenu = document.getElementById('context-menu');
scope.addEventListener("contextmenu", (event) => {
event.preventDefault();
if( event.target.classList.contains('has-content-menu') ||
event.target.closest('.has-content-menu') !== null
){
contextMenu.style.top = event.clientY + 'px';
contextMenu.style.left = event.clientX + 'px';
contextMenu.style.display = 'block';
}else{
contextMenu.style.display = 'none';
}
});
scope.addEventListener("click", (event) => {
contextMenu.style.display = 'none';
});
});
*, ::after, ::before {
box-sizing: border-box;
}
body, html {
height: 100%;
}
#context-menu {
position: fixed;
z-index: 10000;
width: 180px;
background: #ffaaaa;
border-radius: 5px;
display: none;
z-index: 20000;
}
#context-menu.item {
padding: 2px 4px;
font-size: 12px;
color: #eee;
cursor: pointer;
border-radius: inherit;
}
<button class="has-content-menu"> this is data in my DIV</button>
<div id="context-menu">
<div class="item">Option 1</div>
<div class="item">Option 2</div>
</div>
我正在寻找一种简单的方法来隐藏自定义上下文菜单,除非通过按钮或元素。这是我编写的一个简单示例,其中包含一个自定义上下文菜单和一个我希望将其附加到的按钮。我在想也许会有一个事件侦听器来寻找悬停在元素上的事件,或者可能有一个在需要时打开或关闭它的功能?另外我想知道按钮或元素是否没有用 class 或 ID 定义,是否仍然有办法知道你何时结束它,可能是通过坐标(如果可能的话,没必要只是好奇)?这个想法是会有多个元素需要上下文菜单,但是主体中元素周围的一般 space 不应显示自定义菜单。
function view() {
const contextMenu = document.getElementById('context-menu');
const scope = document.querySelector("body");
//body
var listLength = contextMenu.children.length;
for (i = 0; i < listLength; i++)
contextMenu.removeChild(contextMenu.children[0]);
contextMenuadd(contextMenu, "line 1 of context menu", 1);
contextMenuadd(contextMenu, "line 2 of context menu", 2);
contextMenuadd(contextMenu, "line 3 of context menu", 3);
contextMenuadd(contextMenu, "line 4 of context menu", 4);
scope.addEventListener("contextmenu", (event) => {
event.preventDefault();
const {
clientX: mouseX,
clientY: mouseY
} = event;
contextMenu.style.top = `${mouseY}px`;
contextMenu.style.left = `${mouseX}px`;
contextMenu.classList.add('visible');
contextMenu.style.display = 'block';
contextMenu.style.zIndex = 20000;
contextMenu.style.position = 'fixed';
contextMenu.style.width = "360px";
contextMenu.style.borderRadius = "5px";
});
scope.addEventListener("click", (e) => {
if (e.target.offsetParent != contextMenu) {
contextMenu.style.display = 'none';
}
});
};
document.addEventListener('DOMContentLoaded', view);
function contextMenuadd(contextMenu, menustring, count) {
var action = function(e) {
//menuLink;
let currentRow = $(event.target)[0].parentElement;
var index = parseInt(currentRow.row);
var value = currentRow.textContent;
en(href, '_self');
};
var menuitem = document.createElement('LI');
menuitem.addEventListener('click', action);
menuitem.classList.add("hotspot__item");
menuitem.innerHTML = '<a href="#">' + menustring + '</a>';
menuitem.row = count;
contextMenu.appendChild(menuitem);
};
document.addEventListener('click', function(e) {
let inside = (e.target.closest('#container'));
if (!inside) {
let contextMenu = document.getElementById('contextMenuId');
contextMenu.setAttribute('style', 'display:none');
}
});
#context-menu {
position: fixed;
z-index: 10000;
width: 180px;
background: #ffaaaa;
border-radius: 5px;
display: none;
}
#context-menu.item {
padding: 2px 4px;
font-size: 12px;
color: #eee;
cursor: pointer;
border-radius: inherit;
}
<body id="allofit">
<header>
<h2>Context Menu Example</h2>
</header>
<!-- <gm:figure-group> -->
<div id='sdi_canvas1' style="width:400px; height:400px">
<button id="container"> this is data in my DIV</button>
</div>
<div id="context-menu" class="context-menu"
oncontextmenu="ShowMenu('contextMenu',event)" style="display:none">
<div class="item">Option 1</div>
<div class="item">Option 2</div>
</div>
</body>
这里有一个fiddle供参考JSFiddle
您是否尝试过使用 'mouseover' 和 'mouseout' 事件?
如果这是您要找的,请告诉我:
const menu = document.querySelector('.menu')
const btn = document.getElementById('btn');
btn.addEventListener('mouseover', () => {
menu.style.display = "block";
});
btn.addEventListener('mouseout', () => {
menu.style.display = "none";
})
.menu {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<button id="btn">Hover me</button>
<ul class="menu">
<li>Test 1</li>
<li>Test 1</li>
</ul>
</body>
</html>
- 您可以向所有将显示自定义的元素添加 class 上下文菜单。
- 和
oncontextmenu
,您检查元素是否包含 class 然后相应地切换上下文菜单。
试试这个
document.addEventListener('DOMContentLoaded', () => {
const scope = document.querySelector("body");
const contextMenu = document.getElementById('context-menu');
scope.addEventListener("contextmenu", (event) => {
event.preventDefault();
if( event.target.classList.contains('has-content-menu') ||
event.target.closest('.has-content-menu') !== null
){
contextMenu.style.top = event.clientY + 'px';
contextMenu.style.left = event.clientX + 'px';
contextMenu.style.display = 'block';
}else{
contextMenu.style.display = 'none';
}
});
scope.addEventListener("click", (event) => {
contextMenu.style.display = 'none';
});
});
*, ::after, ::before {
box-sizing: border-box;
}
body, html {
height: 100%;
}
#context-menu {
position: fixed;
z-index: 10000;
width: 180px;
background: #ffaaaa;
border-radius: 5px;
display: none;
z-index: 20000;
}
#context-menu.item {
padding: 2px 4px;
font-size: 12px;
color: #eee;
cursor: pointer;
border-radius: inherit;
}
<button class="has-content-menu"> this is data in my DIV</button>
<div id="context-menu">
<div class="item">Option 1</div>
<div class="item">Option 2</div>
</div>