为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

MMMHUHU 2023-04-27 15:10:15
我正在尝试仅使用 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 }))
查看完整描述

5 回答

?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

根据我对你的问题的理解,你希望用结果“替换”正常的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 片段中被阻止。

这绝对是很多代码来创建一个奇怪和不常见的浏览器行为。所以我不会推荐任何人使用它。




查看完整回答
反对 回复 2023-04-27
?
大话西游666

TA贡献1817条经验 获得超14个赞

如果您想在菜单中打开“在新标签页中打开”和“在新窗口中打开”选项,为什么只使用 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>


每当单击时,上面的代码将在新选项卡中打开。右键单击时,还会有一个在新选项卡中打开和在新窗口中打开的选项。


“target”属性指定链接将在何处打开;下面是一些例子:


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"


查看完整回答
反对 回复 2023-04-27
?
哔哔one

TA贡献1854条经验 获得超8个赞

如果我理解正确的话,你必须创建一个自定义的contextmenu. 所以这是一个例子。


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>


查看完整回答
反对 回复 2023-04-27
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

document.getElementById("anchor-el").addEventListener("click", function() {

    var link = document.getElementById('anchor-el').getAttribute("href");

    window.open(link,'_blank');

});


查看完整回答
反对 回复 2023-04-27
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

打开本机系统上下文菜单,例如默认的右键单击上下文菜单是不可能的。

您当然可以使用 jQuery 创建自己的上下文菜单,例如:

https://swisnl.github.io/jQuery-contextMenu/


作为如何使用库的示例:

 $(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>


查看完整回答
反对 回复 2023-04-27
  • 5 回答
  • 0 关注
  • 139 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信