15

我正在contextmenu使用 jQuery 捕捉事件,如下所示:

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

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

使用类似下面的东西可以捕捉到一些情况,但不是几乎所有情况:

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

它不会在以下情况下执行:

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

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

4

2 回答 2

9

以下代码可能会对您有所帮助。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);
于 2012-10-09T14:12:32.180 回答
2

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

小提琴: 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 的鼠标和键盘上进行测试和验证。移动/触摸支持未知。

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

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

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

示例中的 textarea 只是为了提供其他可用于焦点处理的内容。

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

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

于 2020-05-17T22:53:25.917 回答