Какие события я должен слушать, чтобы скрыть пользовательское контекстное меню в JavaScript - PullRequest
0 голосов
/ 26 мая 2018

Интересно, какие события я должен слушать, чтобы скрыть свое пользовательское контекстное меню, элемент <div>, отображаемый из обработчика событий oncontextmenu, как и в собственном.

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Есть несколько действий, которые закрывают собственное контекстное меню:

  • Щелкните снаружи: Прослушайте document.onmousedown и, вДля того, чтобы клики других (действительных) элементов не всплывали и не закрывали контекстное меню, вы должны остановить его распространение в промежуточном обработчике с помощью Event.stopPropagation.

    document.onclick также будет работать, но контекстное меню будет оставаться видимым до тех пор, пока вы не отпустите кнопку мыши, а не исчезнет только при нажатии.

    В сенсорных устройствах вам следует прослушать document.touchstart, поскольку некоторые устройства, такие как iPad, не запускают события click.

  • Нажатие Esc : Прослушивание document.onkeydown и проверьте, является ли нажатая клавиша Esc проверкой KeyboardEvent.keyCode, KeyboardEvent.which и KeyboardEvent.key.

  • Изменение вкладки / окна : прослушивание window.onblur.

  • Прокрутка мыши: В Chrome, liСтен для document.onmousewheel.Посмотрите здесь подробный ответ о том, как обнаружить колесо мыши в разных браузерах: колесо мыши, колесо и DOMMouseScroll в JavaScript .

    Собственное контекстное меню закрывается, когда это происходит, независимо от того,если на странице есть прокрутка или нет, по крайней мере, в Chrome на Windows 10.

Вот простой пример с некоторыми из упомянутых мной опций:

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 также есть проверка, чтобы предотвратить щелчок правой кнопкой мыши по контекстному меню и его позиционирование.

0 голосов
/ 26 мая 2018

Используйте событие oncontextmenu.

el.addEventListener('contextmenu', function(ev) {
    ev.preventDefault();
    // here what you wanna show for example the customised context menu 
    // myContextMenu();
    return false;
}, false);

Не забудьте вернуть false, в противном случае стандартное контекстное меню все равно появится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...