У меня есть простой SVG, который содержит треугольник и меняет цвет заливки при нажатии:
const toggleFill = (element) => {
if (element.style.fill === 'silver') {
element.style.fill = 'grey';
} else {
element.style.fill = 'silver';
}
};
const svg = document.querySelector('svg');
svg.addEventListener('click', () => toggleFill(svg));svg {
height: 70px;
width: 80px;
}<svg viewBox = "0 0 90 78" style = "fill: silver">
<polygon points = "0 78, 45 0, 90 78" stroke = "black"/>
</svg>Проблема в том, что щелчок в любом месте ограничивающей рамки SVG (за пределами треугольника) также вызывает событие click. Я хотел бы ограничить его переключением цвета заливки только при нажатии на сам треугольник, а не на его прозрачный фон.
Согласно этому связанному вопросу , мое желаемое поведение должно быть поведением по умолчанию, поскольку предполагается, что события-указатели по умолчанию соответствуют поведению visiblePainted. Тем не менее, это не то, что я вижу ни в Firefox, ни в Chrome, и даже его явная установка не имеет никакого эффекта.
@Terry В моем реальном коде я изменяю содержимое SVG программно, поэтому гораздо удобнее привязать обработчик кликов к самому элементу SVG.
Если это так, не могли бы вы проверить e.target, чтобы увидеть, на что нажимают? Если e.target === e.currentTarget (т.е. SVG нажимается), то вы ничего не делаете
Проблема с этим подходом заключается в том, что я разбиваю эти треугольники на мозаику, и их ограничивающие рамки перекрываются, поэтому e.target на самом деле является другим элементом SVG, чем тот, по которому щелкнули.
Ваш тестовый пример должен отражать вашу реальную проблему в этом случае, иначе вы получите всевозможные ответы, которые вы не сможете использовать.



Проблема здесь в том, что элемент <svg> является частью HTML-страницы. Там поведение хит-тестирования не определено:
Эта спецификация не определяет поведение событий указателя на самом внешнем элементе svg для изображений SVG, которые встроены по ссылке или включению в другой документ, например, перехватывает ли самый внешний элемент svg, встроенный в документ HTML, события щелчка мыши; будущие спецификации могут определить это поведение, но для целей этой спецификации поведение зависит от реализации.
Если вы посмотрите pointer-events в контексте HTML, вы не найдете более или менее ничего:
Хотя это свойство изменяет нормальное поведение проверки попадания, эта нормальная проверка попадания в настоящее время не указана. Существует широкая интероперабельность в отношении, казалось бы, очевидных частей этой проблемы, но есть бесчисленное множество нюансов и краеугольных случаев, которые были бы очень полезны от подробной спецификации. CSS-WG будет очень признательна за помощь в написании такой спецификации.
Так что на данный момент кажется, что браузеры относятся к самому внешнему элементу <svg> как к любому другому блоку, и события щелчка фиксируются внутри всего блока рамки.
Но это верно только для самого внешнего элемента <svg>. Вложите внутрь еще один <svg> (или лучше элемент <g>) и прикрепите к нему прослушиватель событий, и ожидаемое поведение paintedVisible по умолчанию будет восстановлено:
const toggleFill = (element) => {
if (element.style.fill === 'silver') {
element.style.fill = 'grey';
} else {
element.style.fill = 'silver';
}
};
const g = document.querySelector('svg > g');
g.addEventListener('click', () => toggleFill(g));svg {
height: 70px;
width: 80px;
}<svg viewBox = "0 0 90 78">
<g style = "fill: silver">
<polygon points = "0 78, 45 0, 90 78" stroke = "black"/>
</g>
</svg>Или еще проще, добавьте событие клика к полигону и тогда вам не нужен g
@RobertLongson проверьте комментарии к вопросу, ОП отклонил это решение.
Рассматривали ли вы привязку событий щелчка к элементам, которые вы рисуете, например.
document.querySelector('svg polygon').addEventListener...?