Skip to content

Sometimes the property 'autoHide' has some problem #723

Description

@YonSunZhen

Hi, when i use contextMenu on kityminder, set autoHide to true, and it is not work. the demo as follows:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>test</title>

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">

  <link type="text/css" rel="stylesheet" href="./assets/styles/jquery.contextMenu.css">
  <link type="text/css" rel="stylesheet" href="./assets/styles/font-awesome/css/font-awesome.min.css">
</head>

<body>
  <div id="minder-container1" style="width: 1000px; height: 800px;"></div>

  <script type="text/javascript" src="./assets/js/jquery-1.6.2.min.js"></script>
  <script type="text/javascript" src="./assets/js/jquery.ui.position.min.js"></script>
  <script type="text/javascript" src="./assets/js/jquery.contextMenu.js"></script>
  <script type="text/javascript" src="./assets/js/kity.js"></script>
  <script type="text/javascript" src="./assets/js/kityminder.core.modified.js"></script>
  
  <script>
    const renderData = {
      "root": {
          "data": {
              "text": "百度产品",
              "image": "https://www.baidu.com/img/bd_logo1.png?where=super",
              "imageSize": { "width": 270, "height": 129 }
          },
          "children": [
              { "data": { "text": "新闻" } },
              { "data": { "text": "网页", "priority": 1 } },
              { "data": { "text": "贴吧", "priority": 2 } },
              { "data": { "text": "知道", "priority": 2 } },
              { "data": { "text": "音乐", "priority": 3 } },
              { "data": { "text": "图片", "priority": 3 } },
              { "data": { "text": "视频", "priority": 3 } },
              { "data": { "text": "地图", "priority": 3 } },
              { "data": { "text": "百科", "priority": 3 } },
              { "data": { "text": "更多", "hyperlink": "http://www.baidu.com/more" } }
          ]
      }
    }
    const minder = new kityminder.Minder({
      renderTo: '#minder-container1'
    });
    minder.importJson(renderData);

    $.contextMenu({
      selector: 'g[id^="minder_node"]',
      autoHide: true,
      callback: (itemKey, opt) => { },
      events: {
        preShow: options => { },
        show: options => { },
        hide: options => { }
      },
      build: ($trigger, e) => {
        return {
          items: {
            addField: {
              name: 'Add',
              icon: 'fa-dot-circle-o',
              callback: async (itemKey, opt, rootMenu, originalEvent) => {

              }
            },
            sep2: '---------',
            remove: {
              name: 'Delete',
              icon: 'fa-dot-circle-o',
              callback: (itemKey, opt, rootMenu, originalEvent) => {

              }
            }
          }
        }
      }
    })
  </script>
</body>
</html>

and when i update the code as follows, it works.

if (opt.autoHide) {
          // mouse position handler
          $(document).on('mousemove.contextMenuAutoHide', function (e) {
            // need to capture the offset on mousemove,
            // since the page might've been scrolled since activation
            var pos = $trigger.offset();

            if ($trigger.outerWidth() === 0 && $trigger.outerHeight() === 0) {
              const nodeId = $trigger[0].getAttribute('id');
              const path = $(`#${nodeId} [id^='node_outline']`)[0];
              const pathInfo = path.getBBox();
              const width = pathInfo.width;
              const height = pathInfo.height;
              pos.right = pos.left + width;
              pos.bottom = pos.top + height;
            } else {
              pos.right = pos.left + $trigger.outerWidth();
              pos.bottom = pos.top + $trigger.outerHeight();
            }

            // pos.right = pos.left + $trigger.outerWidth();
            // pos.bottom = pos.top + $trigger.outerHeight();

            if (opt.$layer && !opt.hovering && (!(e.pageX >= pos.left && e.pageX <= pos.right) || !(e.pageY >= pos.top && e.pageY <= pos.bottom))) {
              /* Additional hover check after short time, you might just miss the edge of the menu */
              setTimeout(function () {
                if (!opt.hovering && opt.$menu !== null && typeof opt.$menu !== 'undefined') {
                  opt.$menu.trigger('contextmenu:hide');
                }
              }, 50);
            }
          });
 }

i guess that $trigger.outerWidth() and $trigger.outerHeight() could not get the width and height of element,because the element is svg.

kityminder

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions