【问题标题】:Custom Context Menu Position on right clicking svg element右键单击 svg 元素上的自定义上下文菜单位置
【发布时间】:2021-04-07 22:25:34
【问题描述】:

我正在尝试将 Bootstrap 4 下拉菜单实现为上下文菜单。 一切正常,但下拉的lefttop css 属性面临问题。

DOM 结构?

<div class="col">
    <div class="dropdown-menu dropdown-menu-right shadow-sm" style="width: 15rem;" id="contextMenu">
        <a class="dropdown-item" href="#">Action</a>
        <a class="dropdown-item" href="#">Another action</a>
        <a class="dropdown-item" href="#">Something else here</a>
        <div class="dropdown-divider"></div>
        <a class="dropdown-item" href="#">Separated link</a>
    </div>
    <div class="h-75">
        <svg id="preview" class="shadow" height="100%" viewBox="0 0 1920 1080"
             preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
            <g class="sjx-svg-wrapper">
                <image id="blabla" class="drag-svg"
                       href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" height="200"
                       width="200"/>
            </g>
        </svg>
    </div>
</div>

我尝试了什么?

    $(document).on("contextmenu", 'g.sjx-svg-wrapper', function (e) {
        // TRIES HERE
        let left = e.offsetX;
        let top = e.offsetY;

        $("#contextMenu").css({
            display: "block",
            left: left,
            top: top
        }).addClass("show");

        return false;
    });

有什么问题?

问题是下拉菜单并没有像我们右键单击时出现的正常上下文菜单那样准确地显示在指针上。

而且当 svg 容器的宽度发生变化时,下拉位置会错位(即使再次右键单击)。

我尝试过使用偏移量的其他解决方案,但没有达到目的。 所以请提供一个可靠的方法来解决这个问题。

【问题讨论】:

    标签: jquery svg bootstrap-4 position mouse


    【解决方案1】:

    也许只是使用event.pageXevent.pageY 而不是event.offsetXevent.offsetY...

    .offsetX:

    MouseEvent 接口的 offsetX 只读属性提供了鼠标指针 X 坐标中该事件与目标节点的填充边缘之间的偏移量。

    .pageX:

    MouseEvent 接口的 pageX 只读属性返回鼠标单击时相对于整个文档左边缘的 X(水平)坐标(以像素为单位)。

    $(document).on("contextmenu", 'g.sjx-svg-wrapper', function(e) {
      // TRIES HERE
      let left = e.pageX;
      let top = e.pageY;
    
      $("#contextMenu").css({
        display: "block",
        left: left,
        top: top
      }).addClass("show");
    
      return false;
    });
    #contextMenu{
      display:none;
      position: absolute;
      padding: 20px;
      background-color: white;
      border: 1px solid red;
      box-shadow: 2px 2px grey;
      
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="col">
      <div class="dropdown-menu dropdown-menu-right shadow-sm" style="width: 15rem;" id="contextMenu">
        <a class="dropdown-item" href="#">Action</a>
        <a class="dropdown-item" href="#">Another action</a>
        <a class="dropdown-item" href="#">Something else here</a>
        <div class="dropdown-divider"></div>
        <a class="dropdown-item" href="#">Separated link</a>
      </div>
      <div class="h-75">
        <svg id="preview" class="shadow" height="100%" viewBox="0 0 1920 1080" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg">
                <g class="sjx-svg-wrapper">
                    <image id="blabla" class="drag-svg"
                           href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" height="200"
                           width="200"/>
                </g>
            </svg>
      </div>
    </div>
    
    <div id="contextMenu">CONTEXT</div>

    【讨论】:

    • 谢谢伙计。它在 sn-p 中工作,但不在我的页面上。它放错了那里。顺便说一句,我现在才想通。我有一个问题,为什么我们不使用 e.clientXe.clientY 而不是 pageX 和 pageY?
    • 我认为您的绝对定位元素#contextMenu 可能在一个相对定位的元素内部,而不是body... --- 关于.clientX,它返回相对于视口的位置.
    • 正是男人。下拉菜单不在正文中,而是在相对定位的元素内。现在一切都只是作为 sn-p 工作。非常感谢
    【解决方案2】:

    我想我只是想通了:

    我刚刚做的是从e.clientXe.clientY坐标(基本上是页面上的鼠标位置)中减去容器(宽度变化)的位置坐标(x,y)。

    答案如下:

    var prevElm = $('.h-75').offset();
    
    let left = (e.clientX - prevElm.left) + 15;
    let top = (e.clientY - prevElm.top) + 45;
    

    我认为这仅适用于我的案例页面,其他人可能只需要 e.clientXe.clientY

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 2017-04-22
      相关资源
      最近更新 更多