How to add a custom right-click menu to a webpage?

后端 未结 19 1253
广开言路
广开言路 2020-11-22 15:54

I want to add a custom right-click menu to my web application. Can this be done without using any pre-built libraries? If so, how to display a simple custom right-click menu

相关标签:
19条回答
  • 2020-11-22 16:28

    Here is a very good tutorial on how to build a custom context menu with a full working code example (without JQuery and other libraries).

    You can also find their demo code on GitHub.

    They give a detailed step-by-step explanation that you can follow along to build your own right-click context menu (including html, css and javascript code) and summarize it at the end by giving the complete example code.

    You can follow along easily and adapt it to your own needs. And there is no need for JQuery or other libraries.

    This is how their example menu code looks like:

    <nav id="context-menu" class="context-menu">
        <ul class="context-menu__items">
          <li class="context-menu__item">
            <a href="#" class="context-menu__link" data-action="View"><i class="fa fa-eye"></i> View Task</a>
          </li>
          <li class="context-menu__item">
            <a href="#" class="context-menu__link" data-action="Edit"><i class="fa fa-edit"></i> Edit Task</a>
          </li>
          <li class="context-menu__item">
            <a href="#" class="context-menu__link" data-action="Delete"><i class="fa fa-times"></i> Delete Task</a>
          </li>
        </ul>
      </nav>
    

    A working example (task list) can be found on codepen.

    0 讨论(0)
  • 2020-11-22 16:30

    A combination of some nice CSS and some non-standard html tags with no external libraries can give a nice result (JSFiddle)

    HTML

    <menu id="ctxMenu">
        <menu title="File">
            <menu title="Save"></menu>
            <menu title="Save As"></menu>
            <menu title="Open"></menu>
        </menu>
        <menu title="Edit">
            <menu title="Cut"></menu>
            <menu title="Copy"></menu>
            <menu title="Paste"></menu>
        </menu>
    </menu>
    

    Note: the menu tag does not exist, I'm making it up (you can use anything)

    CSS

    #ctxMenu{
        display:none;
        z-index:100;
    }
    menu {
        position:absolute;
        display:block;
        left:0px;
        top:0px;
        height:20px;
        width:20px;
        padding:0;
        margin:0;
        border:1px solid;
        background-color:white;
        font-weight:normal;
        white-space:nowrap;
    }
    menu:hover{
        background-color:#eef;
        font-weight:bold;
    }
    menu:hover > menu{
        display:block;
    }
    menu > menu{
        display:none;
        position:relative;
        top:-20px;
        left:100%;
        width:55px;
    }
    menu[title]:before{
        content:attr(title);
    }
    menu:not([title]):before{
        content:"\2630";
    }
    

    The JavaScript is just for this example, I personally remove it for persistent menus on windows

    var notepad = document.getElementById("notepad");
    notepad.addEventListener("contextmenu",function(event){
        event.preventDefault();
        var ctxMenu = document.getElementById("ctxMenu");
        ctxMenu.style.display = "block";
        ctxMenu.style.left = (event.pageX - 10)+"px";
        ctxMenu.style.top = (event.pageY - 10)+"px";
    },false);
    notepad.addEventListener("click",function(event){
        var ctxMenu = document.getElementById("ctxMenu");
        ctxMenu.style.display = "";
        ctxMenu.style.left = "";
        ctxMenu.style.top = "";
    },false);
    

    Also note, you can potentially modify menu > menu{left:100%;} to menu > menu{right:100%;} for a menu that expands from right to left. You would need to add a margin or something somewhere though

    0 讨论(0)
  • 2020-11-22 16:30
    <script>
    function fun(){
    document.getElementById('menu').style.display="block";
    }
    
    </script>
    <div id="menu" style="display: none"> menu items</div>
    
    <body oncontextmenu="fun();return false;">
    

    What I'm doing up here

    1. Creat your own custom div menu and set the position: absolute and display:none in case.
    2. Add to the page or element to be clicked the oncontextmenu event.
    3. Cancel the default browser action with return false.
    4. User js to invoke your own actions.

    0 讨论(0)
  • 2020-11-22 16:31

    Was very useful for me. For the sake of people like me, expecting the drawing of menu, I put here the code I used to make the right-click menu:

    $(document).ready(function() {
    
    
      if ($("#test").addEventListener) {
        $("#test").addEventListener('contextmenu', function(e) {
          alert("You've tried to open context menu"); //here you draw your own menu
          e.preventDefault();
        }, false);
      } else {
    
        //document.getElementById("test").attachEvent('oncontextmenu', function() {
        //$(".test").bind('contextmenu', function() {
        $('body').on('contextmenu', 'a.test', function() {
    
    
          //alert("contextmenu"+event);
          document.getElementById("rmenu").className = "show";
          document.getElementById("rmenu").style.top = mouseY(event) + 'px';
          document.getElementById("rmenu").style.left = mouseX(event) + 'px';
    
          window.event.returnValue = false;
    
    
        });
      }
    
    });
    
    // this is from another SO post...  
    $(document).bind("click", function(event) {
      document.getElementById("rmenu").className = "hide";
    });
    
    
    
    function mouseX(evt) {
      if (evt.pageX) {
        return evt.pageX;
      } else if (evt.clientX) {
        return evt.clientX + (document.documentElement.scrollLeft ?
          document.documentElement.scrollLeft :
          document.body.scrollLeft);
      } else {
        return null;
      }
    }
    
    function mouseY(evt) {
      if (evt.pageY) {
        return evt.pageY;
      } else if (evt.clientY) {
        return evt.clientY + (document.documentElement.scrollTop ?
          document.documentElement.scrollTop :
          document.body.scrollTop);
      } else {
        return null;
      }
    }
    .show {
      z-index: 1000;
      position: absolute;
      background-color: #C0C0C0;
      border: 1px solid blue;
      padding: 2px;
      display: block;
      margin: 0;
      list-style-type: none;
      list-style: none;
    }
    
    .hide {
      display: none;
    }
    
    .show li {
      list-style: none;
    }
    
    .show a {
      border: 0 !important;
      text-decoration: none;
    }
    
    .show a:hover {
      text-decoration: underline !important;
    }
    <!-- jQuery should be at least version 1.7 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script src="contextmenu.js"></script>
    <link rel="stylesheet" href="contextmenu.css" />
    
    
    <div id="test1">
      <a href="www.google.com" class="test">Google</a>
      <a href="www.google.com" class="test">Link 2</a>
      <a href="www.google.com" class="test">Link 3</a>
      <a href="www.google.com" class="test">Link 4</a>
    </div>
    
    <!-- initially hidden right-click menu -->
    <div class="hide" id="rmenu">
      <ul>
        <li>
          <a href="http://www.google.com">Google</a>
        </li>
    
        <li>
          <a href="http://localhost:8080/login">Localhost</a>
        </li>
    
        <li>
          <a href="C:\">C</a>
        </li>
      </ul>
    </div>

    0 讨论(0)
  • 2020-11-22 16:31

    Try This

    $(function() {
    var doubleClicked = false;
    $(document).on("contextmenu", function (e) {
    if(doubleClicked == false) {
    e.preventDefault(); // To prevent the default context menu.
    var windowHeight = $(window).height()/2;
    var windowWidth = $(window).width()/2;
    if(e.clientY > windowHeight && e.clientX <= windowWidth) {
      $("#contextMenuContainer").css("left", e.clientX);
      $("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
      $("#contextMenuContainer").css("right", "auto");
      $("#contextMenuContainer").css("top", "auto");
    } else if(e.clientY > windowHeight && e.clientX > windowWidth) {
      $("#contextMenuContainer").css("right", $(window).width()-e.clientX);
      $("#contextMenuContainer").css("bottom", $(window).height()-e.clientY);
      $("#contextMenuContainer").css("left", "auto");
      $("#contextMenuContainer").css("top", "auto");
    } else if(e.clientY <= windowHeight && e.clientX <= windowWidth) {
      $("#contextMenuContainer").css("left", e.clientX);
      $("#contextMenuContainer").css("top", e.clientY);
      $("#contextMenuContainer").css("right", "auto");
      $("#contextMenuContainer").css("bottom", "auto");
    } else {
      $("#contextMenuContainer").css("right", $(window).width()-e.clientX);
      $("#contextMenuContainer").css("top", e.clientY);
      $("#contextMenuContainer").css("left", "auto");
      $("#contextMenuContainer").css("bottom", "auto");
    }
     $("#contextMenuContainer").fadeIn(500, FocusContextOut());
      doubleClicked = true;
    } else {
      e.preventDefault();
      doubleClicked = false;
      $("#contextMenuContainer").fadeOut(500);
    }
    });
    function FocusContextOut() {
     $(document).on("click", function () {
       doubleClicked = false; 
       $("#contextMenuContainer").fadeOut(500);
       $(document).off("click");           
     });
    }
    });
    

    http://jsfiddle.net/AkshayBandivadekar/zakn7Lwb/14/

    0 讨论(0)
  • 2020-11-22 16:33

    According to the answers here and on other 'flows, I've made a version that looks like the one of Google Chrome, with css3 transition. JS Fiddle

    Lets start eazy, since we have the js above on this page, we can worry about the css and layout. The layout that we will be using is an <a> element with a <img> element or a font awesome icon (<i class="fa fa-flag"></i>) and a <span> to show the keyboard shortcuts. So this is the structure:

    <a href="#" onclick="doSomething()">
      <img src="path/to/image.gif" />
      This is a menu option
      <span>Ctrl + K</span>
    </a>
    

    We will put these in a div and show that div on the right-click. Let's style them like in Google Chrome, shall we?

    #menu a {
      display: block;
      color: #555;
      text-decoration: no[...]
    

    Now we will add the code from the accepted answer, and get the X and Y value of the cursor. To do this, we will use e.clientX and e.clientY. We are using client, so the menu div has to be fixed.

    var i = document.getElementById("menu").style;
    if (document.addEventListener) {
      document.addEventListener('contextmenu', function(e) {
        var posX = e.clientX;
        var posY = e.client[...]
    

    And that is it! Just add the css transisions to fade in and out, and done!

    var i = document.getElementById("menu").style;
    if (document.addEventListener) {
      document.addEventListener('contextmenu', function(e) {
        var posX = e.clientX;
        var posY = e.clientY;
        menu(posX, posY);
        e.preventDefault();
      }, false);
      document.addEventListener('click', function(e) {
        i.opacity = "0";
        setTimeout(function() {
          i.visibility = "hidden";
        }, 501);
      }, false);
    } else {
      document.attachEvent('oncontextmenu', function(e) {
        var posX = e.clientX;
        var posY = e.clientY;
        menu(posX, posY);
        e.preventDefault();
      });
      document.attachEvent('onclick', function(e) {
        i.opacity = "0";
        setTimeout(function() {
          i.visibility = "hidden";
        }, 501);
      });
    }
    
    function menu(x, y) {
      i.top = y + "px";
      i.left = x + "px";
      i.visibility = "visible";
      i.opacity = "1";
    }
    body {
      background: white;
      font-family: sans-serif;
      color: #5e5e5e;
    }
    
    #menu {
      visibility: hidden;
      opacity: 0;
      position: fixed;
      background: #fff;
      color: #555;
      font-family: sans-serif;
      font-size: 11px;
      -webkit-transition: opacity .5s ease-in-out;
      -moz-transition: opacity .5s ease-in-out;
      -ms-transition: opacity .5s ease-in-out;
      -o-transition: opacity .5s ease-in-out;
      transition: opacity .5s ease-in-out;
      -webkit-box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
      -moz-box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
      box-shadow: 2px 2px 2px 0px rgba(143, 144, 145, 1);
      padding: 0px;
      border: 1px solid #C6C6C6;
    }
    
    #menu a {
      display: block;
      color: #555;
      text-decoration: none;
      padding: 6px 8px 6px 30px;
      width: 250px;
      position: relative;
    }
    
    #menu a img,
    #menu a i.fa {
      height: 20px;
      font-size: 17px;
      width: 20px;
      position: absolute;
      left: 5px;
      top: 2px;
    }
    
    #menu a span {
      color: #BCB1B3;
      float: right;
    }
    
    #menu a:hover {
      color: #fff;
      background: #3879D9;
    }
    
    #menu hr {
      border: 1px solid #EBEBEB;
      border-bottom: 0;
    }
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
    <h2>CSS3 and JAVASCRIPT custom menu.</h2>
    <em>Stephan Stanisic | Lisence free</em>
    <p>Right-click anywhere on this page to open the custom menu. Styled like the Google Chrome contextmenu. And yes, you can use <i class="fa fa-flag"></i>font-awesome</p>
    <p style="font-size: small">
      <b>Lisence</b>
      <br /> "THE PIZZA-WARE LICENSE" (Revision 42):
      <br /> You can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a Pizza in return.
      <br />
      <a style="font-size:xx-small" href="https://github.com/KLVN/UrbanDictionary_API#license">https://github.com/KLVN/UrbanDictionary_API#license</a>
    </p>
    <br />
    <br />
    <small>(The white body background is just because I hate the light blue editor background on the result on jsfiddle)</small>
    <div id="menu">
      <a href="#">
        <img src="http://puu.sh/nr60s/42df867bf3.png" /> AdBlock Plus <span>Ctrl + ?!</span>
      </a>
      <a href="#">
        <img src="http://puu.sh/nr5Z6/4360098fc1.png" /> SNTX <span>Ctrl + ?!</span>
      </a>
      <hr />
      <a href="#">
        <i class="fa fa-fort-awesome"></i> Fort Awesome <span>Ctrl + ?!</span>
      </a>
      <a href="#">
        <i class="fa fa-flag"></i> Font Awesome <span>Ctrl + ?!</span>
      </a>
    </div>

    0 讨论(0)
提交回复
热议问题