浏览器上下文菜单是否有关闭事件

问题描述 投票:12回答:2

我正在使用jQuery这样捕获contextmenu事件:

$(document.body).on("contextmenu", function(e){
    //do stuff here
});

到目前为止,很好。现在,我想在关闭时执行一些代码,但是似乎找不到正确的解决方案。

使用类似以下内容的方法可以捕获某些情况,但不是全部:

$(document.body).on("contextmenu click", function(e){});

在以下情况下不会执行:

  • 浏览器失去焦点
  • 在上下文菜单中选择了一个选项
  • 用户单击浏览器中不在页面上的任何位置

note:我没有使用jQuery上下文菜单,我只是使用它来捕获事件。

javascript jquery contextmenu jquery-events
2个回答
6
投票

以下代码可能会对您有所帮助。 jsfiddle

var isIntextMenuOpen ;
$(document).on("contextmenu", function(e){

    isIntextMenuOpen = true;
});
function hideContextmenu(e){
       if(isIntextMenuOpen ){
            console.log("contextmenu closed ");
       }

     isIntextMenuOpen = false;
}
$(window).blur(hideContextmenu);

$(document).click(hideContextmenu);

0
投票

我需要检测上下文菜单何时关闭,因此我想出了一个解决方案。

小提琴:https://jsfiddle.net/kexp0nmd/1/

var premenuelem;

var TempContextMenuCloseHandler = function(e) {
console.log('closed!');
//console.log(e);
	window.removeEventListener('keyup', TempContextMenuCloseHandler, true);
	window.removeEventListener('mousedown', TempContextMenuCloseHandler, true);
	window.removeEventListener('focus', TempContextMenuCloseHandler, true);

	var focuselem = document.getElementById('tempfocus');
	if (focuselem === document.activeElement)  premenuelem.focus();
	focuselem.style.display = 'none';
};

var TempContextMenuHandler = function(e) {
console.log('open!');
//console.log(e);
	premenuelem = document.activeElement;

	var focuselem = document.getElementById('tempfocus');
	focuselem.style.display = 'block';
	focuselem.focus();

	window.addEventListener('keyup', TempContextMenuCloseHandler, true);
	window.addEventListener('mousedown', TempContextMenuCloseHandler, true);
	window.addEventListener('focus', TempContextMenuCloseHandler, true);
};

window.addEventListener('contextmenu', TempContextMenuHandler, true);
html, body { min-height: 100%; }
<textarea></textarea>

<div id="tempfocus" tabIndex="-1" style="left: 0; bottom: 0; height: 50px; width: 100%; background-color: #CCCCCC; display: none; position: fixed; outline: none;"></div>

截至2020年5月,经过测试和验证,可以在Edge,Firefox 76和Chrome 80上同时使用鼠标和键盘。移动/触摸支持未知。

此解决方案的关键方面是使用上面带有tabIndex的元素。通过在上下文菜单出现之前显示焦点并将焦点移动到该元素(窃取焦点),将导致Edge和Chrome在用户稍后关闭上下文菜单时发送焦点更改事件。我将div的背景设为灰色,以便可以看到它-在生产中,使其成为透明背景,然后根据需要对其进行样式设置。

keyup处理程序在键盘关闭上下文菜单时捕获Escape / Enter键的释放。 mousedown处理程序仅在Firefox中捕获鼠标按下事件。

据我所知,无法确定用户选择了哪个选项,或者即使他们确实选择了选项,也无法确定。至少,它允许在所有主要浏览器中一致地检测上下文菜单的打开/关闭。

示例中的textarea只是为了给焦点处理提供其他功能。

虽然此解决方案涉及临时焦点窃取,但它是最干净的跨浏览器解决方案,直到浏览器供应商和W3C向DOM添加一个'exitcontextmenu'事件或类似事件为止。

我刚遇到的一个小错误:显示上下文菜单并切换到另一个应用程序会关闭上下文菜单,但不会立即触发已关闭的事件。但是,切换回Web浏览器后,事件将触发,并且关闭处理程序将运行。在窗口中添加“模糊”捕获可能会解决该问题,但随后我必须重新测试所有内容,并且可能会破坏某些内容(例如,打开上下文菜单时出现火灾模糊)。在极少数情况下,这种情况可能会发生,并且处理程序仍会触发,这不值得修复-只是明显地延迟了。

© www.soinside.com 2019 - 2024. All rights reserved.