admin管理员组文章数量:1418437
I have an svg element I'd like to be able to click and drag separately. As far as I can tell in D3, clicking fires the "drag end" event (and possibly also drag start?). In the code below, simply clicking the circle gives it a red outline:
var svg = d3.select('body').append('svg');
var g = svg.append('g');
var c = g.append('circle').attr('r', 20).attr('cx', 25).attr('cy', 25)
.call(d3.drag().on('drag', dragged).on('end', end))
.on('click', clicked);
function dragged() {
d3.select(this).attr('fill', 'green').attr('cx', d3.event.x).attr('cy', d3.event.y);
}
function end() {
d3.select(this).attr('fill', 'red').attr('stroke', 'red').attr('stroke-width', 5);
}
function clicked() {
if (d3.event.defaultPrevented) return;
d3.select(this).attr('fill', 'blue');
}
fiddle
How do you register a click callback without triggering the drag.end callback?
It seems like most of the questions and blocks about clicking and dragging seem to want to suppress the click action on dragging, so are not relevant.
- d3v5.7 (current)
I have an svg element I'd like to be able to click and drag separately. As far as I can tell in D3, clicking fires the "drag end" event (and possibly also drag start?). In the code below, simply clicking the circle gives it a red outline:
var svg = d3.select('body').append('svg');
var g = svg.append('g');
var c = g.append('circle').attr('r', 20).attr('cx', 25).attr('cy', 25)
.call(d3.drag().on('drag', dragged).on('end', end))
.on('click', clicked);
function dragged() {
d3.select(this).attr('fill', 'green').attr('cx', d3.event.x).attr('cy', d3.event.y);
}
function end() {
d3.select(this).attr('fill', 'red').attr('stroke', 'red').attr('stroke-width', 5);
}
function clicked() {
if (d3.event.defaultPrevented) return;
d3.select(this).attr('fill', 'blue');
}
fiddle
How do you register a click callback without triggering the drag.end callback?
It seems like most of the questions and blocks about clicking and dragging seem to want to suppress the click action on dragging, so are not relevant.
- d3v5.7 (current)
1 Answer
Reset to default 8Since mouseup indicates a click's pletion and the end of a drag you could skip the click event and simply add some logic to determine if a drag occured:
// track action:
var wasMoved = false;
// Drag event:
function dragged() {
d3.select(this).attr('fill', 'green').attr('cx', d3.event.x).attr('cy', d3.event.y);
wasMoved = true; // or alternatively, measure the change in distance.
}
// Mouse up event: drag end & click:
function end() {
if(wasMoved) {
// It was a drag:
d3.select(this).attr('fill', 'red').attr('stroke', 'red').attr('stroke-width', 5);
}
// Otherwise it was a click:
else {
d3.select(this).attr('fill', 'blue');
}
wasMoved = false; // reset for next drag.
}
Now we can only trigger one action on mouseup: drag end or what we wanted on click:
var svg = d3.select('body').append('svg');
var g = svg.append('g');
var drag = d3.drag().on("drag", dragged).on("end",end);
var c = g.append('circle')
.attr('r', 20).attr('cx', 25).attr('cy', 25)
.call(drag)
var wasMoved = false;
function dragged() {
d3.select(this).attr('fill', 'green').attr('cx', d3.event.x).attr('cy', d3.event.y);
wasMoved = true;
}
function end() {
if(wasMoved) {
// It was a drag:
d3.select(this).attr('fill', 'red').attr('stroke', 'orange').attr('stroke-width', 5);
}
// It was a click:
else {
d3.select(this).attr('fill', 'blue');
}
wasMoved = false;
}
<script src="https://cdnjs.cloudflare./ajax/libs/d3/5.0.0/d3.min.js"></script>
本文标签: javascriptHow to prevent d3drag()on(39end39 from firing on(39click39Stack Overflow
版权声明:本文标题:javascript - How to prevent d3.drag().on('end' from firing .on('click' - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745263811a2650478.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论