我正在尝试修复我正在处理的一些事件代码。在这种特殊情况下,我需要能够订阅click
上的svg:circle
事件。但是,还需要将圆移动到mousedown
上的z-index的顶部,以便可以将该元素拖动到其他元素的顶部。
完成此操作的方法是将元素从DOM中取出,并使用我从http://bl.ocks.org/eesur/4e0a69d57d3bfc8a82c2使用的辅助函数将其重新插入正确的位置。这样做的问题在于,事件链似乎已损坏,将元素移出了dom阻止了click
事件触发。
我想知道是否有人可以提出一种更好的方法来确保click
正确触发,但仍然允许在拖动生命周期中的某处更改z-index?
这个小示例显示了z-index的变化方式,但click事件不会在控制台中触发。元素再次位于顶部时,再次单击它确实可以正确触发单击。
d3.selectAll("circle")
.on("mousedown", function() {
d3.select(this).moveToFront();
})
.on("click", function() {
var fill = d3.select(this).style("fill");
console.log("You clicked on : " + fill);
});
d3.selection.prototype.moveToFront = function() {
return this.each(function() {
this.parentNode.appendChild(this);
});
};
.red {
fill: red;
}
.blue {
fill: blue;
}
.green {
fill: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>
<svg width="600" height="600">
<circle class="red" cx="50" cy="50" r="50" />
<circle class="blue" cx="100" cy="100" r="50" />
<circle class="green" cx="150" cy="150" r="50" />
</svg>
最佳答案
我想知道问题是否出在d3
上,所以我用纯JS编写了等效内容,并且在Chrome上的结果与d3
完全一样。我可以通过将click
替换为mouseup
并将其与mousedown
元素进行比较来使其工作,就像我的评论一样。您在评论中表示,由于其他项目限制,您无法使用该解决方案。我认为我还是应该发布解决方案,因为有人提到FF和IE中的行为是不同的。
const circles = Array.from(document.getElementsByTagName('circle'));
let mousedown;
for (let circle of circles) {
circle.addEventListener('mousedown', (e) => {
mousedown = e.target;
e.target.parentNode.appendChild(e.target);
}, false);
circle.addEventListener('mouseup', (e) => {
if (mousedown === e.target) {
console.log('You clicked on : ' + window.getComputedStyle(e.target).fill);
}
mousedown = null;
}, false);
}
.red {
fill: red;
}
.blue {
fill: blue;
}
.green {
fill: green;
}
<svg width="600" height="600">
<circle class="red" cx="50" cy="50" r="50" />
<circle class="blue" cx="100" cy="100" r="50" />
<circle class="green" cx="150" cy="150" r="50" />
</svg>