Вы можете использовать d3.event.on
для временного переопределения прослушивателей событий.Таким образом, чтобы программно прервать перетаскивание во время самого события перетаскивания, мы можем использовать:
d3.event.on("drag", null)
d3.event.on("end", null)
Это временно удаляет функции, назначенные каждому слушателю события.Вы заметите, что я тоже удаляю событие завершения - в противном случае оно продолжит прослушивание мыши вверх, независимо от того, назначена ли функция прослушивателю события «перетаскивания».
Эта функция описана в d3-dragevent.on:
event.on (typenames, [listener])
Эквивалентно drag.on, но применяется только к текущему жесту перетаскивания.Перед началом жеста перетаскивания создается копия текущего слушателя события перетаскивания.Эта копия привязана к текущему жесту перетаскивания и изменена с помощью event.on.Это полезно для временных слушателей, которые получают события только для текущего жеста перетаскивания.( source )
В приведенном ниже примере события перетаскивания временно удаляются из круга, когда он попадает в линию.Пользовательское событие отправляется, чтобы указать, что перетаскивание было программно прервано.Все события записываются в журнал - это означает, что события завершения, перетаскивания и прерывания работают должным образом:
var svg = d3.select("svg");
var drag = d3.drag()
.on("drag", function() {
log(); // to log events as they are triggered.
var selection = d3.select(this);
// Update the circle as normal (but don't let cx exceed the line visually):
selection.attr("cx", d3.event.x > 300 ? 300 : d3.event.x)
.attr("cy", d3.event.y);
// If event.x > 300, interrupt drag:
if(d3.event.x > 300) {
// Disable the drag events temporarily
d3.event.on("drag", null)
d3.event.on("end", null)
// Optionally trigger some alternative event
selection.dispatch("interrupted");
}
})
.on("end", function() {
log();
})
var circle = svg.select("circle")
.call(drag)
.on("interrupted", function() {
d3.select(this)
.transition()
.attr("fill","orange")
.attr("cx",250)
.transition()
.attr("fill","steelblue");
log();
})
function log() {
console.log(d3.event.type);
}
.as-console-wrapper { max-height: 40% !important; }
circle { cursor: pointer ; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="300">
<circle cx="100" cy="50" fill="steelblue" r="10"></circle>
<line x1="305" x2="305" y1="0" y2="400" stroke-width="1" stroke="black"></line>
</svg>