是否可以用 link 上下文菜单替换 html 上下文菜单?

Is it possible to replace html context menu with link context menu?

我正在构建自定义 linkbox 组件,类似于此页面上的 linkbox:http://siteimprove-accessibility.net/Demo/Page/

示例代码:

export const Linkbox = ({}) => {
   const linkRef = useRef(null);

   return (
     // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
     <div
       role="region"
       tabIndex={0} // eslint-disable-line jsx-a11y/no-noninteractive-tabindex
       onKeyPress={(e) => {
         if (e.key === 'Enter') {
           linkRef.current.click();
         }
       }}
       onClick={() => {
       linkRef.current.click();
       }}
     >
     <div className="someClassName">
       <div role="heading">Title of the linkbox</div>
       <p>Main text of the linkbox</p>
       <a ref={linkRef} tabIndex={-1} href="https://google.com">
         Link to google
       </a>
     </div>
   </div>
  );
};

现在 link 框的问题是,如果我在 link 框内右键单击,我不会得到默认的 link 上下文菜单,它有如下选项(在新选项卡中打开,在新 window 中打开,然后复制 link 地址)。无论我在 link 框内的哪个位置单击鼠标右键,我都希望打开默认的 link 上下文菜单。

我知道这可以通过创建一个 linkbox 来实现,方法是将整个内容包装在锚标记内。但是根据这个a11y分析,这个策略带来了a11y问题:

https://saavutettavuusmalli.hel.fi/en/toteutus-ja-ohjelmistotestaus/link-box-pattern-notes-on-technical-implementation/

In its typical implementation, a link box is challenging for screenreader users. Often, there is either a single link (anchor) tag which encompasses the entire box — rendering the box very difficult to navigate, comprehend, and interact with when using assistive technology

那么是否可以打开用户单击 link 时获得的相同上下文菜单 (https://developer.mozilla.org/en-US/docs/Web/API/Element/contextmenu_event)?就像以编程方式覆盖当前打开的菜单,并将其替换为用户单击 link?

时弹出的上下文菜单

编辑:我不希望实现整个自定义上下文菜单,因为那样我就必须处理所有语言版本。我只想打开与用户单击 link.

时打开的上下文菜单相同的上下文菜单

由于 contextmenu 事件在 mouseup 事件之后才会触发,您可以在 mousedown 事件上将 link 元素放置在光标当前位置下当用户松开鼠标右键时,将出现 link 的上下文菜单。

let link = document.createElement('a');
link.classList.add('contextlink');
//remove the link from the dom right after the contextmenu appears
link.addEventListener('contextmenu', () => {
  setTimeout(()=>link.remove(), 1)
});
document.addEventListener('mousedown', e => {
  //flag to see if we right clicked in a box
  let inBox = e.target.classList.contains('box');
  //if it is the left mouse or not in the box
  //return right away
  if (e.button == 0 || !inBox) return;
  
  //change the href to one set in the element's data-* attribute
  link.href = '/' + e.target.dataset['link'];
  //position it so it is under the cursor
  link.style.left = (e.clientX - 5) + 'px';
  link.style.top = (e.clientY - 5) + 'px';
  //add it to the dom
  document.body.append(link);
})
.boxes {
  display: flex;
  flex-direction: row;
  height: 100px;
}

.box {
  flex:1 1 auto;
  height:100%;
  margin-right:10px;
  border:1px solid;
}

.contextlink {
  position: fixed;
  width: 10px;
  height: 10px;
  z-index: 1000;
}
<div class="boxes">
  <div class="box" data-link="test"></div>
  <div class="box" data-link="page2"></div>
  <div class="box" data-link="404"></div>
</div>