Состояние наведения SVG на нескольких слоях, а не только на верхнем слое

Я хочу отобразить дерево решений в виде 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, а не только к верхнему слою?


Последующий вопрос: Есть ли способ сделать более широкий путь, на котором применяется состояние зависания, чтобы мне не нужно было точно над линией?

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
0
838
1

Ответы 1

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>

Другие вопросы по теме