如何仅通过带有指针事件的SVG传递点击?

eph*_*ron 4 javascript css svg click pointer-events

我有一个SVG用按钮覆盖div。我知道我可以通过设置“ pointer-events:none;”来通过SVG传递鼠标事件。为我的SVG。但是,当我这样做时,SVG将不再识别鼠标事件。

<body>
  <div id="website">
    <form action="input_button.htm">
      <p>
        <textarea cols="20" rows="4" name="text"></textarea>
        <input type="button" name="Text 1" value="show text" 
         onclick="this.form.text.value='Test'">
      </p>
    </form>
  </div>
  <div id="svgRect">
    <svg width="1845" height="140">
      <rect id="r0"></rect>
    </svg>
  </div>
</body>
Run Code Online (Sandbox Code Playgroud)

我希望我的SVG能够识别鼠标何时位于其上方,但将点击传递到其下方的元素(div /按钮/ ...)。因此,我的SVG应该仅是悬停事件的目标,而我的按钮应该是单击事件的目标。

在其他一些方法中,我尝试过这样的方法:-没有任何效果。

.on("mousedown", function(d,i){
   d3.select("#r0")
     .style("pointer-events", "none");
   d3.select("#website")
     .style("pointer-events", "auto");}
.on("mouseup", function(d,i){
   d3.select("#r0")
     .style("pointer-events", "auto");
   d3.select("#website")
     .style("pointer-events", "none");
}
Run Code Online (Sandbox Code Playgroud)

这个想法是当我按下鼠标按钮时禁用指针事件,并在释放它时再次启用它们。

有人知道这个问题的解决方案或解决方案吗?谢谢!

Jes*_*CMD 8

这是一个更简单的解决方案:保留 pointer-events: none;在 svg 中,但添加pointer-events: fill到多边形、路径或任何按钮,这样,空白空间是透明的,但按钮可以单击

/sf/answers/2052330661/


eph*_*ron 5

我找到了解决问题的方法。使用该elementFromPoint(x,y);功能可以遍历所有基础元素。我编写了一个辅助函数,用于检查第一个所选元素是否为SVG-如果为SVG,则其显示设置为“无”,然后选择下一个元素。

function get_element_under_svg(x,y){
    var resulting_element;
    var first_element = document.elementFromPoint(x,y);
    //check if first_element is a svg
    if (first_element.nodeName == "rect") {
      _display = first_element.style.display;    //save display of svg
      first_element.style.display = "none";      // make svg invisible
      resulting_element = document.elementFromPoint(x,y); 
      first_element.style.display = _display;    // reset display
    } else {
      resulting_element = first_element;
    }
    return resulting_element;
  }  
  return lower_element;
}
Run Code Online (Sandbox Code Playgroud)

归根结底,我设置pointer-events: auto了SVG和div:

#website{
  pointer-event: auto;
}
svg{
  pointer-event: auto;
}
Run Code Online (Sandbox Code Playgroud)

在我的svg中,添加了以下内容:

.on("click", function(d,i) {
  var element = get_element_under_rect( mouse.x, mouse.y );
  element.click(); // simulate click on the underlying element
}); 
Run Code Online (Sandbox Code Playgroud)

通过这种方法,我的SVG仍然能够接收悬停或点击事件,同时能够将点击传递给基础元素。另请参阅https://developer.mozilla.org/zh-CN/docs/Web/API/document.elementFromPoint

感谢其他方法!