右击定制菜单,菜单位置动态变化

117 阅读1分钟

需求:鼠标右击出现菜,并且菜单要随着点击位置距离窗口位置而变化,避免出现菜单被挡住的情况

好的,开始码代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html {
        background-color: darkcyan;
        color: #fff;
      }
      .parent {
        position: relative;
      }
      .menu {
        position: absolute;
        opacity: 0;
        padding: 10px;
        background-color: rgb(225, 120, 220);
      }
    </style>
    <script>
      document.oncontextmenu = (e) => {
        e.preventDefault();
        const menuDom = document.getElementsByClassName("menu")[0];
        const { clientX, clientY} = e;
        menuDom.style.opacity = 1;
        menuDom.style.left = clientX + "px";
        menuDom.style.top = clientY + "px";
      };
    </script>
  </head>
  <body>
    <div class="parent">
      <div class="menu">
        <ul>
          <li>活动一</li>
          <li>活动二</li>
          <li>活动三</li>
          <li>活动四</li>
          <li>活动五</li>
          <li>活动六</li>
          <li>活动七</li>
        </ul>
      </div>
    </div>
  </body>
</html>
 

chrome-capture-2025-1-24.gif

可以看到,在边缘位置会出现菜单 被挡住的情况

解决思路:我们需要获取右击位置距离浏览器左上顶点的距离,screenX, screenY,将这个距离与浏览器宽度、高度比较

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html {
        background-color: darkcyan;
        color: #fff;
      }
      .parent {
        position: relative;
      }
      .menu {
        position: absolute;
        opacity: 0;
        padding: 10px;
        background-color: rgb(225, 120, 220);
      }
    </style>
    <script>
      document.oncontextmenu = (e) => {
        e.preventDefault();
        const menuDom = document.getElementsByClassName("menu")[0];
        const windowWidth = document.documentElement.clientWidth;
        const winHeight = document.documentElement.clientHeight;
        const menuWidth = menuDom.clientWidth;
        const menuHight = menuDom.clientHeight;

        const { clientX, clientY, screenX, screenY } = e;

        const posX = screenX <= windowWidth / 2 ? clientX : clientX - menuWidth;
        const posY = screenY <= winHeight / 2 ? clientY : clientY - menuHight;
       
        menuDom.style.opacity = 1;
        menuDom.style.left = posX + "px";
        menuDom.style.top = posY + "px";
      };
    </script>
  </head>
  <body>
    <div class="parent">
      <div class="menu">
        <ul>
          <li>活动一</li>
          <li>活动二</li>
          <li>活动三</li>
          <li>活动四</li>
          <li>活动五</li>
          <li>活动六</li>
          <li>活动七</li>
        </ul>
      </div>
    </div>
  </body>
</html>

77.gif 右击的时候, 浏览器会出现默认的菜单, 用preventDefault

 <script>
  document.oncontextmenu = (e) => {
    e.preventDefault();
  };
</script>