Я хочу отобразить дерево решений в виде SVG с большей интерактивностью. Здесь есть разные пути, и при наведении курсора их непрозрачность увеличивается. Но состояние зависания, похоже, применяется только к верхнему элементу.
#flow polyline {
stroke: #0071bc;
stroke-opacity: 0;
stroke-width: 8px;
mix-blend-mode: color;
}
#flow polyline:hover {
stroke-opacity: 1;
}
https://jsfiddle.net/yv82f3ud/
Как я могу применить событие наведения ко всем зависшим полилиниям SVG, а не только к верхнему слою?
Последующий вопрос: Есть ли способ сделать более широкий путь, на котором применяется состояние зависания, чтобы мне не нужно было точно над линией?






How can I apply the hover event on all hovered svg polylines, not only the top layer?
Нет тривиального пути. Вам нужно будет определить, какой раздел вы прошли, определить, какие из них следует выделить, а затем вручную выделить их самостоятельно.
Is there a way to have a wider path are on which the hover state is applied so I don't have to be exactly over the line?
Да, используйте отдельную прозрачную более толстую линию
.line {
stroke: grey;
stroke-width: 2;
}
.line-wider {
stroke: transparent;
stroke-width: 40;
}
g:hover .line {
stroke: blue;
}<svg>
<g>
<path d = "M0,50 L 300,50" class = "line"/>
</g>
<g>
<path d = "M0,100 L 300,100" class = "line"/>
<path d = "M0,100 L 300,100" class = "line-wider"/>
</g>
</svg>Вы можете использовать события наведения указателя мыши на толстые прозрачные участки линии как способ определить, какой участок вы прошли, и на основании этого сделать выделение.
Примерно так:
// Add event listener to each "line-wider" path, that highlights the sections
var sections = document.querySelectorAll(".line-wider");
sections.forEach(function(elem) {
elem.addEventListener("mouseover", doHover);
elem.addEventListener("mouseout", clearHover);
});
var highlightedSections = {
's1': '.s1, .s11, .s12, .s111, .s112, .s121, .s122',
's11': '.s1, .s11, .s111, .s112',
's12': '.s1, .s12, .s121, .s122',
's111': '.s1, .s11, .s111',
's112': '.s1, .s11, .s112',
's121': '.s1, .s12, .s121',
's122': '.s1, .s12, .s122'
};
function doHover(evt) {
// Which section are we hovering over?
var id = evt.target.id;
// highlightedSections[id] is a CSS selector which selects all the sections which should be highlighted for this hover section
document.querySelectorAll(highlightedSections[id]).forEach( function(elem) {
// Add the "highlight" class to all the matching sections
elem.classList.add("highlight");
});
}
// Remove the "highlight" class from all elements which currently have it set
function clearHover(evt) {
document.querySelectorAll(".highlight").forEach( function(elem) {
elem.classList.remove("highlight");
});
}.line {
fill: none;
stroke: grey;
stroke-width: 2;
}
.line-wider {
fill: none;
stroke: transparent;
stroke-width: 40;
}
.highlight {
stroke: blue;
}<svg width = "400" height = "500">
<!-- top section -->
<path d = "M 200,0 L 200,100" class = "line s1"/>
<path d = "M 200,0 L 200,100" class = "line-wider" id = "s1"/>
<!-- left branch -->
<path d = "M 200,100 L 100,200, 100,300" class = "line s11"/>
<path d = "M 200,100 L 100,200, 100,300" class = "line-wider" id = "s11"/>
<!-- left branch -->
<path d = "M 100,300 L 50,350, 50,450" class = "line s111"/>
<path d = "M 100,300 L 50,350, 50,450" class = "line-wider" id = "s111"/>
<!-- right branch -->
<path d = "M 100,300 L 150,350, 150,450" class = "line s112"/>
<path d = "M 100,300 L 150,350, 150,450" class = "line-wider" id = "s112"/>
<!-- right branch -->
<path d = "M 200,100 L 300,200, 300,300" class = "line s12"/>
<path d = "M 200,100 L 300,200, 300,300" class = "line-wider" id = "s12"/>
<!-- left branch -->
<path d = "M 300,300 L 250,350, 250,450" class = "line s121"/>
<path d = "M 300,300 L 250,350, 250,450" class = "line-wider" id = "s121"/>
<!-- right branch -->
<path d = "M 300,300 L 350,350, 350,450" class = "line s122"/>
<path d = "M 300,300 L 350,350, 350,450" class = "line-wider" id = "s122"/>
</svg>