首页 > 解决方案 > 我应该监听哪些事件来隐藏 JavaScript 中的自定义上下文菜单

问题描述

我想知道我应该听哪些事件来隐藏我的自定义上下文菜单,这是一个<div>从事件处理程序中显示的元素oncontextmenu,就像在本机中一样。

标签: javascriptmouseeventcontextmenudom-eventspopupmenu

解决方案


有多个操作可以关闭本机上下文菜单:

这是一个简单的示例,其中包含我提到的一些选项:

const contextMenu = document.getElementById('contextMenu');
const MARGIN = 10;

document.oncontextmenu = (e) => {
  e.preventDefault();
  
  const target = e.target;

  if (contextMenu === target || contextMenu.contains(target)) {
    // A right-click on the context menu itself (or anything inside it) will NOT reposition it:
    return;
  }
  
  contextMenu.style.left = `${ Math.min(window.innerWidth - contextMenu.offsetWidth - MARGIN, Math.max(MARGIN, e.clientX)) }px`;
  contextMenu.style.top = `${ Math.min(window.innerHeight - contextMenu.offsetHeight - MARGIN, Math.max(MARGIN, e.clientY)) }px`;

  contextMenu.classList.remove('hidden');
};

contextMenu.onmousedown = (e) => {
  // We don't want this click to close the context menu, so we stop its propagation:
  e.stopPropagation();
};

// EVENTS THAT CLOSE THE CONTEXT MENU:

window.onblur = () => {
  contextMenu.classList.add('hidden');
};

document.onmousedown = () => {
  contextMenu.classList.add('hidden');
};

document.onmousewheel = () => {
  contextMenu.classList.add('hidden');
};

document.onkeydown = (e) => {
  if (e.key === 'Escape' || e.which === 27 || e.keyCode === 27) {
    contextMenu.classList.add('hidden');
  }
};
html,
body {
  height: 100%;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0;
  font-family: monospace;
}

#contextMenu {
  box-sizing: border-box;
  padding: 5px;
  width: 200px;
  min-height: 50px;
  max-height: calc(100vh - 20px);
  background: white;
  position: fixed;
  border-radius: 2px;
  box-shadow: 0 0 32px rgba(0, 0, 0, .25);
  transition: box-shadow ease-in 50ms;
}

#contextMenu:hover {
  box-shadow: 0 0 48px rgba(0, 0, 0, .25);
}

#contextMenu:active {
  box-shadow: 0 0 16px rgba(0, 0, 0, .25);
}

#contextMenuImage {
  width: 100%;
  border-radius: 2px;
  display: block;
}

.hidden {
  visibility: hidden;
}
<div id="contextMenu" class="hidden">
  <img id="contextMenuImage" src="https://media1.giphy.com/media/3o7aTskHEUdgCQAXde/giphy.gif" />
</div>

RIGHT-CLICK TO SEE THE CONTEXT MENU

请注意,处理程序内部还有一个检查,oncontextmenu以防止右键单击上下文菜单本身重新定位它。


推荐阅读