是否可以用 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问题:
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>
我正在构建自定义 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问题:
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>