SVG悬停状态不仅在顶层,而且在多层上

时间:2018-09-28 17:03:54

标签: css svg hover polyline

我想将决策树显示为具有某种交互性的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折线,而不仅仅是顶层?


后续问题: 有没有一种方法可以将悬停状态应用到更宽的路径上,所以我不必完全越过线路?

1 个答案:

答案 0 :(得分:1)

  

如何将悬浮事件应用于所有悬浮的svg折线,而不仅仅是顶层?

没有简单的方法。您需要检测结束的部分,确定应该突出显示的部分,然后自己手动突出显示它们。

  

是否有一种方法可以将悬停状态应用到更宽的路径上,所以我不必越过终点线?

是的,使用单独的透明粗线

.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>