如何在按钮或元素上隐藏自定义上下文菜单

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>