【问题标题】:JavaScript event - mouseover attached to SVG rectangles, partially failed to responseJavaScript 事件 - 鼠标悬停附加到 SVG 矩形,部分响应失败
【发布时间】:2022-08-13 20:53:22
【问题描述】:

以下是使用create-react-app 创建的样板并呈现的唯一组件是TestComponent。在TestComponent 中,它渲染了一个显示几个矩形的 SVG。 (screenshot attached)。

mouseover 事件附加到 SVG 矩形。我的期望是一旦我将鼠标移过矩形,控制台将打印鼠标位置的日志 - (clientX, clientY)。

该行为适用于大多数矩形,但不是全部。 以下矩形正在工作:

  • 第 1、第 2、第 5、第 6、第 7 个垂直矩形

3rd and 4th 垂直矩形不打印 clientXclientY

为了确保这些矩形之间没有重叠,我删除了所有水平矩形。和 mouseover 事件是一样的,第三个和第四个垂直矩形 mouseover 事件不起作用。

我很想相信这是一个浏览器错误,但我不确定。原因是如果我将 stoke-width 更改为 20px,第三个和第四个矩形会响应 mouseover 事件。但是,如果敲击宽度为 1px,那么无论我在这两个矩形上移动多少次,它都没有任何反应。

我正在使用最新的 Chrome 浏览器 - 版本 104.0.5112.81(官方版本)(64 位)。

index.js

import React from \"react\";
import ReactDOM from \"react-dom\";
import \"./index.css\";
import TestComponent from \"./components/test.jsx\";
import reportWebVitals from \"./reportWebVitals\";

const root = document.getElementById(\"root\");
ReactDOM.render(
  <React.StrictMode>
    <TestComponent />
  </React.StrictMode>,
  root
);
reportWebVitals();

test.jsx

import React, { Component } from \"react\";

export default class TestComponent extends Component {
  onRectMouseOver = (e) => {
    console.log(`${e.clientX} ${e.clientY}`);
  };
  render() {
    const rects = JSON.parse(
      \"[[0, 45, 45, 2370], [1955, 45, 45, 2370], [355, 45, 45, 2370], [710, 45, 45, 2370], [1065, 45, 45, 2370], [1420, 45, 45, 2370], [1775, 45, 45, 2370], [45, 845, 310.0, 45], [45, 1645, 310.0, 45], [400, 845, 310.0, 45], [400, 1645, 310.0, 45], [755, 845, 310.0, 45], [755, 1645, 310.0, 45], [1110, 845, 310.0, 45], [1110, 1645, 310.0, 45], [1465, 845, 310.0, 45], [1465, 1645, 310.0, 45], [1820, 845, 135.0, 45], [1820, 1645, 135.0, 45], [0, 2415, 2000, 45], [0, 0, 2000, 45]]\"
    );

    return (
      <div style={{ width: 5000, height: 3000, backgroundColor: \"grey\" }}>
        <svg
          viewBox=\"0 0 5000 3000\"
          xmlns=\"http://www.w3.org/2000/svg\"
          transform=\"scale(1,-1)\"
        >
          <g>
            {rects &&
              rects.map((rect, index) => {
                let [x, y, width, height] = rect;

                return (
                  <rect
                    x={x}
                    y={y}
                    width={width}
                    height={height}
                    key={index}
                    style={{ fill: \"None\", strokeWidth: 1, stroke: \"black\" }}
                    onMouseOver={(e) => {
                      this.onRectMouseOver(e);
                    }}
                  >
                    <title>
                      x: {x}; y: {x}; width: {width}; height:
                      {height}
                    </title>
                  </rect>
                );
              })}
          </g>
        </svg>
      </div>
    );
  }
}
  • 我确实检查了 Z 轴,当我将鼠标移到第三个和第四个垂直矩形上时,我的鼠标路径上没有第二层 @RobertLongson
  • 我在您的代码中使用了 const rects 来生成 svg。结果与您问题中的图像不同。 viewBox=\"0 0 5000 3000\" 也不适用于您拥有的 svg。您是否使用正确的代码?
  • 我使用了与 div 相同大小的 viewBox,所以比例是 1:1。横梁也使用@enxaneta。代码版本对应截图。就屏幕截图而言,代码是“正确的”,但对于鼠标悬停事件却是不正确的。
  • @RobertLongson 删除了所有水平矩形,以便这些矩形之间没有覆盖。结果是一样的。
  • @RobertLongson @enxaneta 我非常相信这是一个 Chrome 错误。我已通过 Chrome report an issue 向 Chrome 开发团队提出了这个问题。

标签: javascript html reactjs svg dom-events


【解决方案1】:

我热衷于相信这是一个 Chrome 浏览器错误。

它适用于 Firefox - 103.0.2(64 位)。

【讨论】:

    【解决方案2】:

    由于您使用的是fill: none,因此只有边框会触发事件,而不是内部。而且你的每个矩形都有非常窄的笔划,只有 1px 宽(可能会因为“1px 边框模糊”而占用 2px*),所以如果你移动得非常快,可以跳过的不仅仅是第 3 和第 4 个矩形(实际上它不是很难跳过大部分矩形)。

    通过快速移动鼠标,我也可以在 Firefox 上重现该效果。

    (*我的意思是“1px边框模糊”,例如https://vecta.io/blog/5-most-common-problems-faced-by-svg-users 3B的3B。画布也有类似的问题:https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines

    此外,仅使用 Chrome,我只需使用鼠标的超慢水平移动就成功地触发了您的第三个和第四个垂直矩形。 所以,我想实际的问题是你的鼠标指针每单位时间可以移动超过 2px,所以很容易“跳过”边界而不会触发任何东西。 我认为浏览器可以正常工作。

    解决方法 1:一种可能的解决方法是使用fill: transparent(与fill: rgba(0,0,0,0) 相同),因此内部可以触发鼠标事件。那么错过一个矩形就不是那么容易了。 (但可能会有副作用,因为敏感区域现在更大了)。

    解决方法 2:不知何故pointer-events: fill,即使没有填充,它似乎也能正常工作,但后来我认为它具有误导性。 (我现在想知道这是故意的还是错误的,据推测,fill: none 不应该有任何“填充”来触发任何指针事件)。

    【讨论】:

      猜你喜欢
      • 2012-12-29
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2020-08-04
      相关资源
      最近更新 更多