У меня есть визуализация d3 (v5), состоящая из структуры DOM, которая выглядит более или менее похожей на svg > g > etc
. Д. Я настроил прослушиватель масштабирования на svg, например:
this.svg.call(this.zoom.scaleExtent([1/2, 40]).on("zoom" zoomed))
В обработчике "zoom" я трансформирую базовый узел g
который является прямым дочерним элементом svg
. Я вижу множество примеров и руководств, которые устанавливают rect
с единственной целью захвата событий мыши. Я видел учебники, которые делают это, несмотря на наличие svg
который уже покрывает поверхность видового экрана. Почему имея rect
необходимости/полезным? Почему бы просто не использовать svg
?
Это самый безопасный способ убедиться, что события мыши зафиксированы во всем окне просмотра. Когда происходит событие мыши, браузер будет выполнять тестирование с целью определения того, какой элемент становится объектом этого события. Важно понимать, что во время тестирования попадают только графические элементы, и поэтому ни те, ни другие элементы <svg>
и <g>
могут стать прямыми объектами событий мыши, хотя событие может в конечном итоге достичь их, когда оно пузырится до него.
Если у вас есть автономный SVG (то есть тот, который не является частью дерева DOM HTML), спецификация строго определяет:
Обратите внимание, что элемент svg не является графическим элементом, а в совместимом автономном файле SVG самый корневой элемент svg никогда не станет объектом событий указателя, хотя события могут пузыриться в этом элементе.
Тем не менее, для встроенных документов SVG немного другое:
Эта спецификация не определяет поведение событий указателя на самом корневом элементе svg для изображений SVG, которые встроены ссылкой или включением в другой документ, например, является ли элемент rootmost 'svg, встроенный в документ HTML, перехватывает события щелчка мыши; будущие спецификации могут определять это поведение, но для целей этой спецификации поведение специфично для реализации.
Размещение полной шкалы <rect>
охватывающей весь видовой экран для перехвата событий мыши, гарантирует, что тестирование на удар будет работать не в зависимости от окружения SVG, ни от пользовательского агента (например, от браузера), в котором он отображается.
rect.call(d3.zoom())
,rect
будет скрывать svg, или событие всплывет, если уrect
нет обработчиковevent.stopPropagation()
- это вызватьevent.stopPropagation()
илиevent.stopImmediatePropagation()
. Тем не менее, оба способа будут работать: вы можете назначить обработчик для<rect>
или<svg>
. Вероятно, наилучший вариант будет определяться остальными вашими SVG и тем, чего вы пытаетесь достичь. С точки зрения D3, вы чаще всего будете видеть его прикрепленным к<rect>
: bl.ocks.org/mbostock/3680957 .