我正在创建一个示例,说明使用D3拖动行为和CSS {display: table}
样式重新调整大小的单元格的布局。它可以很好地水平拖动,但不能垂直拖动。对于垂直调整大小,d3.event.y
提供的值对我来说没有意义。
这是一个显示工作水平拖动和破碎垂直拖动的小提琴。在拖动时查看控制台输出,可以看到d3.event
在水平拖动时返回的值与d3.mouse()
返回的值相匹配,但在垂直拖动时它们会出现分歧。
我可以通过使用d3.mouse()
y坐标而不是d3.event
y坐标来修复行为。要看到这一点,注释掉"DOESN'T WORK"行并取消注释"WORKS"行。然而,我不明白为什么我需要这样做,它似乎不太通用,因为我必须假设一个鼠标输入,而不是使用更通用的d3.event.
这是一个错误,还是我没有理解这里的东西?
请注意,这个问题似乎遇到了同样的问题,但使用HTML表而不是CSS表。我想把这个问题在两种情况下都出现的记录下来会有帮助。
还请注意,注释掉实际进行垂直调整大小的两行,用"RESIZE CELLS"注释,使d3.event
正常工作。当然,表不会被调整大小。这表明是调整div大小的行为导致d3.event
误入歧途。
好了,我想我已经找到问题所在了。如果查看一下拖动行为的代码,您会注意到dragstart
中用于计算鼠标偏移量的值是基于this.parentNode
的。简而言之,它使用this.parentNode
作为参考点,并假设它在拖动期间是稳定的。您在拖动过程中修改了父节点,因此它的参考点(从技术上讲)变得非常糟糕。在这种情况下,使用d3.mouse
是最好的选择,因为d3.event.y
只有在父节点保持不变的情况下才是可靠的。
这只发生在y方向上的原因是,所有行(这里的父节点)的x位置保持不变,而y分量在拖动过程中发生变化。
相关代码段:
parent = that.parentNode,
function moved() {
var position1 = position(parent, dragId), dx, dy;
//...
dispatch({
type: "drag",
x: position1[0] + dragOffset[0],
y: position1[1] + dragOffset[1],
dx: dx,
dy: dy
});