简体   繁体   English

如何使用 JavaScript 打开锚上下文菜单?

[英]How to open anchor context menu with JavaScript?

I'm trying to open an anchor context menu using only JavaScript, eg for this HTML:我正在尝试仅使用 JavaScript 打开一个锚上下文菜单,例如对于此 HTML:

<html>
  <head></head>
  <body>
    <a href="https://stackoverflow.com" id="anchor-el"> Anchor </a>
  </body>
</html>

I want to open the context menu with the native 'Open in link new tab' and 'Open link in new window' options using just JavaScript.我想仅使用 JavaScript 使用本机“在链接新选项卡中打开”和“在新窗口中打开链接”选项打开上下文菜单。

So far I've tried this, and it seems to successfully dispatch a contextmenu event to the anchor, but the context menu doesn't actually show...到目前为止,我已经试过这一点,它似乎成功地派遣一个contextmenu事件到锚,但在上下文菜单中实际上并没有显示...

document.getElementById('anchor-el').dispatchEvent(new MouseEvent('contextmenu', { bubbles: true }))

From what I understand of your question, you wish to "replace" the normal click event result with the contextmenu result... But with just the two first items of that context menu.从我明白你的问题,你希望“代替”正常的click与事件结果contextmenu结果......但与上下文菜单的只是前两个项目。

That makes it a custom menu that you have to define.这使它成为您必须定义的自定义菜单。 So here is something...所以这里有一些东西......

 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>

NOTE : window.open is blocked in SO snippets for obvious reasons.注意:由于显而易见的原因, window.open在 SO 片段中被阻止。 Try this CodePen for a working demo.试试这个CodePen进行工作演示。

That definitely is a lot of code to create a weird and uncommon browser behavior.这绝对是创建奇怪和不常见的浏览器行为的大量代码。 So I would not recommand anyone to use it.所以我不会推荐任何人使用它。

I posted that because it was a bounty challenge .oO(lol!)我发布它是因为这是一个赏金挑战。oO(大声笑!)

document.getElementById("anchor-el").addEventListener("click", function() {
    var link = document.getElementById('anchor-el').getAttribute("href");
    window.open(link,'_blank');
});

I believe it'll help you.我相信它会帮助你。

If i understood correctly you have to create a custom contextmenu .如果我理解正确,您必须创建一个自定义contextmenu So here is an example.所以这是一个例子。

 const menu = document.querySelector('[data-id=anchor-el]') const anchor = document.getElementById('anchor-el'); anchor.addEventListener('contextmenu', e => { e.preventDefault(); menu.style.top = e.pageX; menu.style.top = e.pageY; menu.style.display = 'block'; }); menu.querySelector('li#newTab').addEventListener('click', (evt) => { evt.preventDefault(); console.log('clicked open in new tab'); window.open(anchor.href); }); menu.querySelector('li#newWin').addEventListener('click', (evt) => { evt.preventDefault(); console.log('clicked open in new window'); window.open(anchor.href, '_blank', 'toolbar=0,location=0,menubar=0'); }); document.body.addEventListener('click', (evt) => { evt.preventDefault(); evt.stopPropagation(); menu.style.display = 'none'; });
 [data-id="anchor-el"] { width: 15rem; display: flex; margin: 0; padding: 0; align-items: stretch; align-content: space-evenly; flex-direction: column; justify-content: space-evenly; box-shadow: 0 0.25rem 0.325rem 0.175rem rgba(0, 0, 0, 0.2); position: relative; display: none; } [data-id="anchor-el"] ul li { width: 100%; list-style: none; margin: 0; padding: 0.5rem; position: relative; color: #000; font-weight: 500; font-size: 1rem; cursor: pointer; } [data-id="anchor-el"] ul li:hover { color: #f00; }
 <a href="https://stackoverflow.com" id="anchor-el"> Anchor </a> <div> <div type="context" data-id="anchor-el"> <ul> <li label="Open in new tab" id="newTab">Open in new tab</li> <li label="Open in new window" id="newWin">Open in new window</li> </ul> </div> </div>

If you want to have Open In New Tab and Open In New Window options in the menu, why just use HTML?如果您想在菜单中具有在新标签页中打开和在新窗口中打开选项,为什么只使用 HTML?

 <html> <head></head> <body> <a href="https://stackoverflow.com" id="anchor-el" target="_blank" title="If you run this snippet and click on this link, it won't work because you need to run it in your own editor"> Anchor </a> </body> </html>

The above code will open in a new tab whenever clicked.每当单击上述代码时,都会在新选项卡中打开。 Also there will be an option for Opening in a new Tab and Opening in a new window, when it is right clicked.当右键单击时,还将有一个选项用于在新选项卡中打开和在新窗口中打开。

The attribute "target" specifies where the link will be opened;属性“target”指定链接的打开位置; Below are some examples:下面是一些例子:

target="_blank" - "Opens in new tab"
target="_self" - "Opens in the same tab"
target="_parent" - "Opens in the parent frame"
target="_top" - "Opens in the full body of the window"

Opening native system context menus, eg the default right click context menu is not possible.无法打开本机系统上下文菜单,例如默认的右键单击上下文菜单。
You can, of cause create your own context menu using jQuery for example:您当然可以使用 jQuery 创建自己的上下文菜单,例如:
https://swisnl.github.io/jQuery-contextMenu/ https://swisnl.github.io/jQuery-contextMenu/

As an example for how to use the library:作为如何使用库的示例:

 $(function() { $.contextMenu({ selector: '#example', trigger: 'left', callback: function(key, options) { var m = "clicked: " + key; window.console && console.log(m) || alert(m); }, items: { "edit": {name: "Edit", icon: "edit"}, "cut": {name: "Cut", icon: "cut"}, copy: {name: "Copy", icon: "copy"}, "paste": {name: "Paste", icon: "paste"}, "delete": {name: "Delete", icon: "delete"}, "sep1": "---------", "quit": {name: "Quit", icon: function(){ return 'context-menu-icon context-menu-icon-quit'; }} } }); /* prevent the default switching to the target site */ $("#example").on("click", function(event) { event.preventDefault(); }); });
 <link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.ui.position.js"></script> <a href="https://google.com" id="example">click me</a>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM