javascript - 如何使用 JavaScript 打开锚上下文菜单?
问题描述
我正在尝试仅使用 JavaScript 打开一个锚上下文菜单,例如对于这个 HTML:
<html>
<head></head>
<body>
<a href="https://stackoverflow.com" id="anchor-el"> Anchor </a>
</body>
</html>
我想仅使用 JavaScript 使用原生的“在链接新选项卡中打开”和“在新窗口中打开链接”选项打开上下文菜单。
到目前为止,我已经尝试过了,它似乎成功地将一个contextmenu
事件发送到锚点,但上下文菜单实际上并没有显示......
document.getElementById('anchor-el').dispatchEvent(new MouseEvent('contextmenu', { bubbles: true }))
解决方案
根据我对您的问题的理解,您希望用结果“替换”正常click
事件contextmenu
结果......但只有该上下文菜单的前两个项目。
这使它成为您必须定义的自定义菜单。所以这里有一些东西......
let contextElements = document.querySelectorAll(".context-anchor")
let myContext = document.querySelector(".context")
let contextItems = document.querySelectorAll(".context-item")
let contextHref
// To add event a listener on each .context-anchor element in order to show a "simulated context menu"
contextElements.forEach(function(ce){
ce.addEventListener("click", function(e){
e.preventDefault()
// Get the click coord to open the context menu at the right place
let clickCoords = {x: e.pageX, y: e.pageY}
// Get the href of the clicked link
contextHref = ce.href
// Create a mouse event
let event = document.createEvent('MouseEvents');
event.initEvent('mycontextmenu', false, true);
// Be ready to handle it
this.addEventListener('mycontextmenu', function (e) {
myContext.style.top = clickCoords.y
myContext.style.left = clickCoords.x
myContext.style.display= "block"
}, false);
// Dispatch it
this.dispatchEvent(event);
})
})
// Listener for the options of that "simulated context menu"
contextItems.forEach(function(ci){
ci.addEventListener("click", function(e){
if(this.getAttribute("data-destination") === "tab"){
window.open(contextHref,"_blank")
}else{
window.open(contextHref,"custom",`width=${0.99*screen.width},height=${0.94*screen.height}`)
}
})
})
// To hide the "simulated context menu" when there is a click anywhere else than on a .context-anchor element
document.addEventListener("click", function(e){
if(myContext.style.display==="block" && e.target.classList.toString().split(" ").indexOf("context-anchor")<0){
myContext.style.display= "none"
}
})
.context{
display: none;
position: absolute;
top: 0;
left: 0;
border: 1px solid lightgrey;
background: white;
margin: 1em;
box-shadow: 2px 2px 2px grey;
min-width: 15em;
}
.context-item{
font-family: "arial";
padding: 0.5em 2em;
}
.context-item:hover{
background: lightgrey;
}
<a href="https://stackoverflow.com" class="context-anchor"> Anchor </a><br>
<br>
<a href="http://hmpg.net/" > Normal anchor </a>
<!-- The simulated context menu -->
<div class="context">
<div class="context-item" data-destination="tab">Open link in a new tab</div>
<div class="context-item" data-destination="window">Open link in a new window</div>
</div>
注意:window.open
由于明显的原因,在 SO 片段中被阻止。试试这个CodePen的工作演示。
这绝对是创建奇怪和不常见的浏览器行为的大量代码。所以我不会推荐任何人使用它。
我发布这个是因为这是一个赏金挑战。oO(哈哈!)
推荐阅读
- android - Android有IDFV吗?
- javascript - 显示来自 html 前代码标记中另一个模板文字中的模板文字的 html
- python - 二进制字符串操作
- django - 在 get_initial 中访问 Django 上下文数据
- java - 如果一个类继承自多个接口并且这些接口具有相同的方法名称和签名。如何提供不同的实现
- excel - 如何为来自不同位置和特定条件的隐藏行创建循环?
- powershell - 将许多数组元素作为单独的参数传递给 Powershell 中的可执行文件
- c# - 如何将对象打印到控制台?
- javascript - 为什么我的 JavaScript Do-While 循环没有带来我想要的结果?
- android - Jetpack compose 从资源中获取 FontFamily