我正在尝试制作各种SVG编辑器.长话短说,我需要将鼠标事件附加到
给定SVG内特定深度的元素.由于各种原因,我无法提前知道身份证.SVG非常庞大,即使不是数千个元素也会有数百个.
d3.selectAll("svg > g > g > g").select("g").on("mouseover", function() { console.log("mouseover"); }).on("mouseout", function() { console.log("mouseout"); }).on("click", function() { console.log("clicked"); });
此代码有效,但它需要很长时间才能开始.假设我有十个这样的元素将匹配特定的选择.似乎在页面加载后的每一秒中,另外一个实际上获得了附加的鼠标事件.我想知道每次d3附加一个事件时我是否可以打印一个控制台事件,或者我怎么知道d3是否完成了附加所需的一切.
基本上这个JSFiddle需要更快地加载鼠标事件.如果等待几秒钟,您会看到越来越多的盒子在工作.
事实证明,这是臭名昭著pointer-events
与fill
麻烦之间的错综复杂的变化。实际上,事件处理程序会立即附加到
元素上。但是,它们会在一段时间内不执行,因为事件在大多数情况下不会进入这些元素。设置pointer-events: all
确实可以轻松解决此问题。
除了技术问题之外,这还是一个很好的例子,说明了为什么您应该提供一个最小的例子,即把事情简化到最低限度。大量的代码使不必要的攻击变得困难。以下代码片段仅包含足以说明问题的代码:
d3.select("g").on("mouseover", function() {
// The difference between below log entries shows, that the event was
// targeted at another element and bubbled up to this handler's element.
console.dir(d3.event.target.tagName); // : actual target for this event
console.dir(this.tagName); // : element this handler is attached to
d3.select(this).select("rect")
.style("fill", "orange");
});
rect {
stroke: red;
stroke-width: 0.2;
stroke-dasharray: 1.5 1.5;
fill:none;
}