Javascript 如何禁用上下文菜单中止的所有单击操作?

Javascript 如何禁用上下文菜单中止的所有单击操作?,javascript,Javascript,我们有自定义的上下文菜单,可以在右键单击时替换浏览器菜单。我们希望能够以浏览器隐藏默认上下文菜单的相同方式中止(隐藏)上下文菜单-在菜单之外的任何位置单击而不注册为单击。该解决方案应同时适用于绑定事件和默认浏览器操作,但不妨碍其他事件的启动,即悬停 一个例子: 在firefox中,右键单击此页面以打开上下文菜单。悬停在 Questions-Tags-Users-Badges-Unanswered 在本页的顶部。即使上下文菜单处于打开状态,高亮显示仍会出现。现在,单击此页面上的文本区域,如顶部的

我们有自定义的上下文菜单,可以在右键单击时替换浏览器菜单。我们希望能够以浏览器隐藏默认上下文菜单的相同方式中止(隐藏)上下文菜单-在菜单之外的任何位置单击而不注册为单击。该解决方案应同时适用于绑定事件和默认浏览器操作,但不妨碍其他事件的启动,即
悬停

一个例子:

在firefox中,右键单击此页面以打开上下文菜单。悬停在

Questions-Tags-Users-Badges-Unanswered
在本页的顶部。即使上下文菜单处于打开状态,高亮显示仍会出现。现在,单击此页面上的文本区域,如顶部的搜索框。关联菜单将隐藏,但光标不会聚焦文本框(除非在关闭菜单的情况下再次单击)

我们如何在JavaScript中模拟这种行为

我们考虑过的被拒绝的选项

  • 在整个页面上使用透明div。问题:这可以捕获任何地方的点击,但会破坏悬停事件和悬停css

  • 检查每个单击处理程序中的上下文菜单打开变量,并将处理程序分配给所有链接和输入元素,以检测上下文菜单打开状态,这将关闭上下文菜单,取消打开状态,并阻止处理程序默认设置。问题:非常草率的代码和维护噩梦


  • 考虑拒绝选项#2的一种变体,其中文档上有一个事件侦听器

    document.addEventListener('click', function (e) {
        if (contextMenuOpen) {
            e.preventDefault();
            e.stopPropagation();
        }
    }, true);
    

    有关
    true
    的更多信息,请查阅
    useCapture
    ,并且。

    Guest
    在事件捕获方面是正确的,但是解决方案有一些小故障。这是一个更稳健的解决方案,可解决以下问题:

  • 不要在右键单击事件中立即关闭右键菜单,右键单击事件在上下文菜单之后立即触发
  • 当上下文菜单打开时,不要让文本字段聚焦-焦点事件首先触发,并且不会被捕获单击事件捕获。我们还需要在焦点上设置捕获处理程序
  • 处理由焦点和单击处理程序产生的问题,这两个处理程序都会触发
  • 为此,需要两个捕获事件处理程序:

    document.addEventListener('focus', function(e){eDocumentFocusCapture(e)}, true);
    document.addEventListener('click', function(e){eDocumentClickCapture(e)}, true);
    
    // If the context menu is open, ignore the focus event.
    eDocumentFocusCapture = function(e){
       if(RowContextMenuIsOpen){
          console.log('focus event sees the menu open: cancel focus, but leave menu be. Click will take care of closing it.');
          e.stopImmediatePropagation();
          e.preventDefault();
          e.target.blur(); // tell the clicked element it is not focused, otherwise you can't focus it until you click elsewhere first!
       }
    }
    
    
    eDocumentClickCapture = function(e){   
    
       // A right click fires immediatly after context menu is fired,
       // we prevent the menu from closing immediately by skipping one right click event
       if(RowContextMenuWasJustOpened===true && e.button===2){
          console.log('right click self bypass');
          RowContextMenuWasJustOpened=false;
          return;
       }
    
       if(this.protected.RowContextMenuIsOpen){
          console.log('click event sees menu open, I will close it.');
          this.HideRowContextMenu();      
          e.stopImmediatePropagation();
          e.preventDefault();      
       }
    }
    

    在我的电脑上(windows上的firefox),使用Ubuntu上的firefox 37,在上下文菜单打开的情况下单击会聚焦文本框,第一次单击不会聚焦,但只会关闭上下文菜单,如前所述。一个小问题:上下文菜单事件触发,然后单击事件触发。这会导致菜单打开,然后立即关闭。+1用于事件捕获。有几个问题需要解决,即处理菜单自动关闭和文本区域可聚焦,因为焦点事件首先触发。