首页 > 解决方案 > 当视图框为负时鼠标事件的svg问题

问题描述

我使用 SVG 来绘制地图。但是当视图框为负值时 - 鼠标事件不起作用。请查看以下小提琴:

<svg 
	id="svg" class="mapNavSVG"
	width="100%" 
	viewBox="27.7333333 -43.2233334 0.2183334 0.0566667"
	preserveAspectRatio="xMidYMid meet" 
	xmlns="http://www.w3.org/2000/svg" 
	xlink="http://www.w3.org/1999/xlink" 
	ev="http://www.w3.org/2001/xml-events" 	
	shape-rendering="geometricPrecision"
	>
  <rect x="27.7333333" y="-43.2233334" width="0.2183334" height="0.0566667" style="fill:#0059b3;" />
  <rect onClick="alert('Test!');" x="27.9408" y="-43.1944975" width="0.006" height="0.006" style="fill:yellow;" />
  </svg>

值是真实的 GPS 坐标。正如你所看到的——当点击黄色矩形时——什么也没发生。

先感谢您。

更新:08.01.2018 在这里发表一些评论和额外的研究后,我发现这个问题的原因是小的实数(非整数)。在 chrome 中问题已修复,但在 64 版中仍然存在 firefox 问题,即使bugzilla 中有问题日志。缩放地图中的所有 SVG 元素对我来说太难了,因为我是从 GIS 软件中获取它们的。感谢大家的帮助。

标签: svg

解决方案


这些是与浏览器相关的计算错误。在以下代码段中,我设置了 px 宽度和高度<svg>以获得可比较的结果。.getBoundingClientRect()黄色矩形报告的宽度在从 返回和从 计算时应该匹配.getBBox(),乘以从 的比例值.getScreenCTM()

var rect = document.querySelector('rect:last-child');
var size = rect.getBBox().width;
console.log('local width:', size);
var scale = rect.getScreenCTM().a;
console.log('screen scale:', scale, 'screen width:', size*scale);
console.log('bounding rect width', rect.getBoundingClientRect().width);
<svg 
	id="svg" class="mapNavSVG"
	width="500px" height="100px"
	viewBox="27.7333333 -43.2233334 0.2183334 0.0566667"
	preserveAspectRatio="xMidYMid meet" 
	xmlns="http://www.w3.org/2000/svg" 
	xlink="http://www.w3.org/1999/xlink" 
	ev="http://www.w3.org/2001/xml-events" 	
	shape-rendering="geometricPrecision"
	>
  <rect x="27.7333333" y="-43.2233334" width="0.2183334" height="0.0566667" style="fill:#0059b3;" />
  <rect x="27.9408" y="-43.1944975" width="0.006" height="0.006" style="fill:yellow;" />
  </svg>

在 Chromium 71/Debian 中,结果(或多或少)匹配:10.588px 到 10.589px。

在 Firefox 60esr/Debian 和 Firefox 64/Windows 中,它们没有:10.589px 到 29.416px 的边界矩形(也在开发工具中报告)。

Edge 和 IE11 计算 10.655px,但边界矩形的值为(原文如此!)1775.275px。至少鼠标事件捕获似乎正确地获取了该区域。

你能从中学到什么?非常小的数字会在某些浏览器上导致大的错误。从网站上的其他问题和以前的经验来看,我认为不要将元素的大小设置为低于 1px 的大小。如果你用 1000 缩放每个数字,错误就会消失:

<svg 
	id="svg" class="mapNavSVG"
	width="100%" 
	viewBox="27733.3333 -43223.3334 218.3334 56.6667"
	preserveAspectRatio="xMidYMid meet" 
	xmlns="http://www.w3.org/2000/svg" 
	xlink="http://www.w3.org/1999/xlink" 
	ev="http://www.w3.org/2001/xml-events" 	
	shape-rendering="geometricPrecision"
	>
  <rect x="27733.3333" y="-43223.3334" width="218.3334" height="56.6667" style="fill:#0059b3;" />
  <rect onClick="alert('Test!');" x="27940.8" y="-43194.4975" width="6" height="6" style="fill:yellow;" />
  </svg>


推荐阅读