我试图用d3和SVG构建一个可拖动的对象。 "目标" object是一个包含" rect"的SVG G元素。作为背景,SVG G元素作为具有点击事件(如网格)的孩子。
我想丢弃从起点拖动点开始的距离小于11的事件;因为"目标"对象具有在拖动距离太短时必须接收单击事件的子项。
我试图回归' true'或者' false'内部'拖动'用于控制此事件何时有效的函数事件;但它没有用。
var x1 =0, y1 =0;
target.call(d3.drag()
.on("start", function () {
x1 =d3.event.x;
y1 =d3.event.y;
return true;
})
.on("drag", function () {
var x2 = d3.event.x;
var y2 = d3.event.y;
var x = x2 - x1;
var y = y2 - y1;
var d2 = x * x + y * y;
var distance = Math.sqrt(d2);
return distance > 10;
}).on("end", function () {
console.log("end");
})
);
现在,使用拖动,我发现了另一个问题: 单击时刻鼠标上的一点移动会导致拖动事件而不是单击事件。
有没有办法解决这个问题而不执行类似假冒'点击?
答案 0 :(得分:0)
我想我的代码片段会做你想要的,尽管不是太复杂。请注意,除非鼠标移动超过阈值,否则不会禁止单击。希望能使本质明确。灵感来自this github issue的讨论。
var target = d3.select('#test');
var x1 =0, y1 =0;
var threshold = 40;
var distanceReached = false;
target.call(d3.drag()
.on("start", function () {
x1 =d3.event.x;
y1 =d3.event.y;
distanceReached = false;
})
.on("drag", function () {
var x2 = d3.event.x;
var y2 = d3.event.y;
var x = x2 - x1;
var y = y2 - y1;
var d2 = x * x + y * y;
var distance = Math.sqrt(d2);
distanceReached = distance > threshold;
if (distanceReached) {
target
.style('left', x2 + 'px')
.style('top', y2 + 'px');
}
}).on("end", function () {
if (distanceReached) {
console.log('drag');
} else {
d3.select(window).on('click.drag', null);
console.log('no drag');
}
})
);
target.on('click', function() {
console.log('click');
});
#test { background:red; position:absolute; height:40px; width:40px; }
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id='test' />