创建一个不消耗点击事件的悬停区域

Create a hover area that doesn't consume click events

我想在悬停在某个元素上时显示工具提示框,我只希望工具提示在用户鼠标离开矢量图形定义的自定义悬停区域时消失。

除了悬停区域会阻止点击事件冒泡到工具提示外,这是可行的,如下所示。

$(document).ready(function() {
  $("#hover-me").mouseenter(function(e) {
    $("#mouse-box").css("visibility", "visible");
    $("#tooltip").show();
  });
  $("#mouse-box").mouseleave(function(e) {
    $("#mouse-box").css("visibility", "hidden");
    $("#tooltip").hide();
  });
});
#tooltip {
  position: absolute;
  top: 20px;
  display: none;
  height: 60px;
}

#hover-me {
  position: absolute;
  top: 40px;
  left: 140px;
}

svg {
  position: absolute;
  left: 0;
  width: 210px;
  height: 83px;
  opacity: 0.03;
  pointer-events: none;
}

svg clipPath rect:first-child {
  width: 90px;
  height: 100%;
  x: 0;
  y: 0;
}

svg clipPath rect:last-child {
  width: 130px;
  height: 35px;
  x: 90px;
  y: 25px;
}

#mouse-box {
  fill: red;
  visibility: hidden;
  width: 100%;
  height: 100%;
  pointer-events: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="tooltip">Can't click</button>
<div id="hover-me">Hover me</div>
<svg>
    <defs>
      <clipPath id="clip">
        <rect/><rect/>
      </clipPath>
    </defs>
    <rect id="mouse-box" clip-path="url(#clip)"/>
</svg>

您可能无法让所有鼠标事件正常运行,但对于 click(),至少,您可以使用隐藏-测试-显示-点击技巧。

$(document).ready(function() {
  $("#hover-me").mouseenter(function(e) {
    $("#mouse-box").css("visibility", "visible");
    $("#tooltip").show();
  });
  $("#mouse-box").mouseleave(function(e) {
    $("#mouse-box").css("visibility", "hidden");
    $("#tooltip").hide();
  });

  $("#mouse-box").click(function(e) {
    $("#mouse-box").hide();
    var elem = document.elementFromPoint(e.pageX, e.pageY);
    $("#mouse-box").show();
    $(elem).click();
  });
  
  $("#tooltip").click(function(e) {
    alert("Clicked!");
  });
});
#tooltip {
  display: none;
  height: 150px;
}

#hover-me {
  position: absolute;
  top: 65px;
  left: 140px;
}

svg {
  position: absolute;
  left: 0;
  width: 210px;
  height: 150px;
  opacity: .03;
  pointer-events: none;
}

svg clipPath rect:first-child {
  width: 70px;
  height: 670px;
  x: 0;
  y: 0;
}

svg clipPath rect:last-child {
  width: 150px;
  height: 35px;
  x: 70px;
  y: 50px;
}

#mouse-box {
  fill: red;
  visibility: hidden;
  width: 100%;
  height: 100%;
  pointer-events: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="tooltip">Tooltip</button>
<div id="hover-me">Hover me</div>
<svg>
    <defs>
      <clipPath id="clip">
        <rect/><rect/>
      </clipPath>
    </defs>
    <rect id="mouse-box" clip-path="url(#clip)"/>
</svg>

我在工具提示中添加了一个 z-index 以使其呈现在悬停区域的顶部。

但是,悬停区域的 mouseleave 处理程序会在鼠标进入工具提示时开始触发,导致它隐藏。

为了解决这个问题,我将 if ($('#tooltip:hover').length === 0) 添加到 mouseleave 处理程序中,这样我仅在鼠标通过其外围退出悬停区域时才隐藏工具提示。

$(document).ready(function() {
  $("#hover-me").mouseenter(function(e) {
    $("#mouse-box").css("visibility", "visible");
    $("#tooltip").show();
  });
  $("#mouse-box").mouseleave(function(e) {
    if ($('#tooltip:hover').length === 0) {
      $("#mouse-box").css("visibility", "hidden");
      $("#tooltip").hide();
    }
  });
});
#tooltip {
  position: absolute;
  top: 20px;
  display: none;
  height: 60px;
  z-index: 10;
}

#hover-me {
  position: absolute;
  top: 40px;
  left: 140px;
}

svg {
  position: absolute;
  left: 0;
  width: 210px;
  height: 83px;
  opacity: 0.03;
  pointer-events: none;
}

svg clipPath rect:first-child {
  width: 90px;
  height: 100%;
  x: 0;
  y: 0;
}

svg clipPath rect:last-child {
  width: 130px;
  height: 35px;
  x: 90px;
  y: 25px;
}

#mouse-box {
  fill: red;
  visibility: hidden;
  width: 100%;
  height: 100%;
  pointer-events: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="tooltip">Can click</button>
<div id="hover-me">Hover me</div>
<svg>
    <defs>
      <clipPath id="clip">
        <rect/><rect/>
      </clipPath>
    </defs>
    <rect id="mouse-box" clip-path="url(#clip)"/>
</svg>