У меня очень общий низкий вопрос о перетаскивании. Мне особенно интересно узнать, что именно определяет, когда событие перетаскивания запускается в D3.js v4. Например, если я перемещаю перетаскиваемый объект очень медленно, событие перетаскивания приведет к срабатыванию каждого пикселя, который я перемещаю. Однако, если я двигаюсь довольно быстро, событие перетаскивания не запускается в корреляции "один к одному" с количеством пикселей, которые я переместил.
В настоящее время я изучаю эту проблему, прежде всего с вкладкой Chrome Dev Performance; Я полагаю, что это (надеюсь) даст мне некоторое представление. Я также знаю, что существуют функции debouncing, которые могут ограничивать количество раз, когда вызывается событие; однако я не знаю или вижу, что у D3 есть это. Я думаю, что причина снижения требований к перетаскиванию имеет какое-то отношение к чему-то, возможно, внутреннему в Chrome, и, возможно, он просто использует какой-то алгоритм для вызова перетаскивания, основываясь на быстром перемещении мыши. Это, скорее всего, самый вероятный ответ, но если кто-то может дать мне некоторое представление о том, как именно это поведение будет определено, я был бы очень благодарен.
Последнее: я также знаю, что иногда, когда вы перемещаете курсор мыши так быстро, что он "выгружает" объект, который вы перетаскиваете, тогда событие перетаскивания не следует вызывать. Однако, даже когда я не "оставляю" объект, который я перетаскиваю, есть еще меньше вызовов для перетаскивания, исходя из того, как быстро я перемещаю курсор мыши.
ps, в то время как я использую D3, эта проблема может очень просто иметь дело с перетаскиванием вообще и не быть чем-то конкретным для D3...
Проблема, которую вы видите, имеет мало общего с D3, это общее поведение JavaScript или, еще лучше, поведение, связанное с браузером: то, что вы видите, является особенностью mousemove
.
Если вы посмотрите на API D3, вы увидите, что в событии "drag" используется mousemove
(или touchmove
для сенсорных устройств):
drag - после перемещения активного указателя (на mousemove или touchmove).
Теперь идет важная информация: mousemove
генерируется браузером. Более важно, что браузер не обязан генерировать событие по какой-либо конкретной ставке, будь то отношение к расстоянию или времени. Кроме того, другие факторы могут влиять на частоту mousemove
, например, на оборудование, которое вы используете.
Итак, если мы предположим (просто для упрощения), что браузер генерирует событие mousemove
каждые 100 мс, у вас есть простое объяснение описанного вами поведения:
Учитывая, что speed = distance/time
, если вы двигаете мышью быстрее, у вас будет меньше событий от точки A до B (то есть расстояние от события mousemove
до следующего будет больше). Если вы двигаете мышью медленнее, у вас будет больше событий из точки A в B (то есть расстояние от события mousemove
до следующего будет меньше). Если вы перемещаете мышь со скоростью менее 1px/100ms (в нашем гипотетическом сценарии), вы получите 1 событие на пиксель.
Наконец, здесь представлена очень простая демонстрация. Нажмите и перетащите в любом месте SVG:
var count = 0;
d3.select("svg").call(d3.drag().on("start", function() {
console.log("drag started")
}).on("drag", function() {
++count;
console.log("drag event " + count)
}).on("end", function() {
count = 0;
console.log("drag ended")
}))
.as-console-wrapper { max-height: 20% !important;}
svg {
border: 1px solid black;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>