从代码中删除上下文菜单项

时间:2016-04-26 04:17:31

标签: javascript browser contextmenu custom-contextmenu

有没有办法在上下文菜单中删除默认项目(例如"在新标签中打开" 右键单击锚元素时)具体的HTML页面?

如果无法做到这一点,是否可以通过" contextmenu" 事件禁止显示默认菜单,告诉我如何显示自定义菜单" preventDefault()方法"

修改:问题的第二部分可能会被视为this preceeding question的副本,但不会被视为@Menon答案。

1 个答案:

答案 0 :(得分:1)

您可能无法隐藏(不显示)“在新标签中打开”选项以获取链接。

如果您要求custom right-click context menus,那么它是重复的。

以下是我为您提供的演示:

(function() {

  
  function clickInsideElement(e, className) {
    var el = e.srcElement || e.target;

    if (el.classList.contains(className)) {
      return el;
    } else {
      while (el = el.parentNode) {
        if (el.classList && el.classList.contains(className)) {
          return el;
        }
      }
    }

    return false;
  }

 
  function getPosition(e) {
    var posx = 0;
    var posy = 0;

    if (!e) var e = window.event;

    if (e.pageX || e.pageY) {
      posx = e.pageX;
      posy = e.pageY;
    } else if (e.clientX || e.clientY) {
      posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
      posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

    return {
      x: posx,
      y: posy
    }
  }

  
  var contextMenuClassName = "context-menu";
  var contextMenuItemClassName = "context-menu__item";
  var contextMenuLinkClassName = "context-menu__link";
  var contextMenuActive = "context-menu--active";

  var taskItemClassName = "task";
  var taskItemInContext;

  var clickCoords;
  var clickCoordsX;
  var clickCoordsY;

  var menu = document.querySelector("#context-menu");
  var menuItems = menu.querySelectorAll(".context-menu__item");
  var menuState = 0;
  var menuWidth;
  var menuHeight;
  var menuPosition;
  var menuPositionX;
  var menuPositionY;

  var windowWidth;
  var windowHeight;

  function init() {
    contextListener();
    clickListener();
    keyupListener();
    resizeListener();
  }

  function contextListener() {
    document.addEventListener("contextmenu", function(e) {
      taskItemInContext = clickInsideElement(e, taskItemClassName);

      if (taskItemInContext) {
        e.preventDefault();
        toggleMenuOn();
        positionMenu(e);
      } else {
        taskItemInContext = null;
        toggleMenuOff();
      }
    });
  }

 
  function clickListener() {
    document.addEventListener("click", function(e) {
      var clickeElIsLink = clickInsideElement(e, contextMenuLinkClassName);

      if (clickeElIsLink) {
        e.preventDefault();
        menuItemListener(clickeElIsLink);
      } else {
        var button = e.which || e.button;
        if (button === 1) {
          toggleMenuOff();
        }
      }
    });
  }

  
  function keyupListener() {
    window.onkeyup = function(e) {
      if (e.keyCode === 27) {
        toggleMenuOff();
      }
    }
  }

  
  function resizeListener() {
    window.onresize = function(e) {
      toggleMenuOff();
    };
  }

 
  function toggleMenuOn() {
    if (menuState !== 1) {
      menuState = 1;
      menu.classList.add(contextMenuActive);
    }
  }

 
  function toggleMenuOff() {
    if (menuState !== 0) {
      menuState = 0;
      menu.classList.remove(contextMenuActive);
    }
  }

  function positionMenu(e) {
    clickCoords = getPosition(e);
    clickCoordsX = clickCoords.x;
    clickCoordsY = clickCoords.y;

    menuWidth = menu.offsetWidth + 4;
    menuHeight = menu.offsetHeight + 4;

    windowWidth = window.innerWidth;
    windowHeight = window.innerHeight;

    if ((windowWidth - clickCoordsX) < menuWidth) {
      menu.style.left = windowWidth - menuWidth + "px";
    } else {
      menu.style.left = clickCoordsX + "px";
    }

    if ((windowHeight - clickCoordsY) < menuHeight) {
      menu.style.top = windowHeight - menuHeight + "px";
    } else {
      menu.style.top = clickCoordsY + "px";
    }
  }

  
  function menuItemListener(link) {
    console.log("Task ID - " + taskItemInContext.getAttribute("data-id") + ", Task action - " + link.getAttribute("data-action"));
    toggleMenuOff();
  }

  
  init();

})();
@import url(http://fonts.googleapis.com/css?family=Roboto:400,300);
 *,
*::before,
*::after {
  box-sizing: border-box;
}
body {
  color: #595959;
  font-family: "Roboto", sans-serif;
  font-size: 16px;
  font-weight: 300;
  line-height: 1.5;
}
.container {
  margin: 0 auto;
  padding: 0 24px;
  max-width: 960px;
}
/* primary header */

.primary-header {
  padding: 24px 0;
  text-align: center;
  border-bottom: solid 2px #cfcfcf;
}
.primary-header__title {
  color: #393939;
  font-size: 36px;
}
.primary-header__title small {
  font-size: 18px;
  color: #898989;
}
/* content */

.content {
  padding: 48px 0;
  border-bottom: solid 2px #cfcfcf;
}
.content__footer {
  margin-top: 12px;
  text-align: center;
}
/* footer */

.primary-footer {
  padding: 24px 0;
  color: #898989;
  font-size: 14px;
  text-align: center;
}
/* tasks */

.tasks {
  list-style: none;
  margin: 0;
  padding: 0;
}
.task {
  display: flex;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: solid 1px #dfdfdf;
}
.task:last-child {
  border-bottom: none;
}
/* context menu */

.context-menu {
  display: none;
  position: absolute;
  z-index: 10;
  padding: 12px 0;
  width: 240px;
  background-color: #fff;
  border: solid 1px #dfdfdf;
  box-shadow: 1px 1px 2px #cfcfcf;
}
.context-menu--active {
  display: block;
}
.context-menu__items {
  list-style: none;
  margin: 0;
  padding: 0;
}
.context-menu__item {
  display: block;
  margin-bottom: 4px;
}
.context-menu__item:last-child {
  margin-bottom: 0;
}
.context-menu__link {
  display: block;
  padding: 4px 12px;
  color: #0066aa;
  text-decoration: none;
}
.context-menu__link:hover {
  color: #fff;
  background-color: #0066aa;
}
<body>
  <header class="primary-header">
    <div class="container">
      <h1 class="primary-header__title">
        My Tasks App <small>using custom context menus</small>
      </h1>
    </div>
  </header>
  <main class="content">
    <div class="container">
      <ul class="tasks">
        <li class="task" data-id="3">
          <div class="task__content">
            Go To Grocery
          </div>
          <div class="task__actions">
            <i class="fa fa-eye"></i>
            <i class="fa fa-edit"></i>
            <i class="fa fa-times"></i>
          </div>
        </li>
        <li class="task" data-id="2">
          <div class="task__content">
            Type Some Code
          </div>
          <div class="task__actions">
            <i class="fa fa-eye"></i>
            <i class="fa fa-edit"></i>
            <i class="fa fa-times"></i>
          </div>
        </li>
        <li class="task" data-id="1">
          <div class="task__content">
            Build An App
          </div>
          <div class="task__actions">
            <i class="fa fa-eye"></i>
            <i class="fa fa-edit"></i>
            <i class="fa fa-times"></i>
          </div>
        </li>
      </ul>
    </div>
  </main>
  <footer class="primary-footer">
    <div class="container">
      <small>&copy; 2015 Context Menu Madness! Demo by Nick Salloum. <a href="building-custom-context-menu-javascript" target="_blank">See article </a></small>
    </div>
  </footer>
  <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>
</body>

如果这是您想要的,请参考duplicate question。但是如果你想编辑正常显示的菜单,那么我认为没有办法做到这一点。