DChop
DChop

Reputation: 21

javascript to show/hide SVG elements when you click other SVG elements

I am making an interactive map and want to show hide different SVG elements when others are clicked. [I started with this}(https://stackoverflow.com/questions/30484743/show-and-hide-elements-inside-svgs) but I don't want all the 'g' elements to hide, only specific ones. I tried changing the getelement tag to id but it didn't seem to work.

updated: got it to target classes and updated my code info. The one textbox I want to stay open is not. I hope I made things more clear, thank you.

    <script type="text/javascript">
        <![CDATA[
        var id = 'name';
        
    function place(id) {
      var gs =  document.getElementsByClassName("textboxes");
    
      // Hide all the elements    
      for (var i = 0; i < gs.length; i++) {
        gs[i].classList.add("hidden");
      }
      // But make sure the one with "id" is visible
      document.getElementById(id).classList.remove("hidden");
    }
        ]]>
        </script>

my map item with the onclick:


    <g onclick="place('accelerator')" id="accelerator-n">
                <a  xlink:href="#">
                    <linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="539.1322" y1="175.0099" x2="543.4789" y2="175.0099">
                    <stop  offset="0" style="stop-color:#A7A9AC"/>
                    <stop  offset="2.965399e-02" style="stop-color:#ACAEB1"/>
                    <stop  offset="0.1582" style="stop-color:#BCBEC0"/>
                    <stop  offset="0.3016" style="stop-color:#C6C7C9"/>
                    <stop  offset="0.4888" style="stop-color:#C9CACC"/>
                    <stop  offset="0.8212" style="stop-color:#CCCDCF"/>
                    <stop  offset="1" style="stop-color:#D1D3D4"/>
                </linearGradient>
                <polygon class="st4" points="544.2,340.9 542.9,341.8 542.8,160.8 544.3,159.3            "/>
                <polygon class="st6" points="542.4,175.6 539.1,175.3 540.2,174.4 543.5,174.4            "/>
                <polygon class="st5" points="539.3,341.9 543,341.9 543,160.6 538.7,160.5            "/>
                </a>
                </g>

two textboxes, the introinfo box should be seen on loading and others hide/show depending on what map element you click on:


    <g id="introinfo" class="textboxes">
        <rect x="28.8" y="33.8" class="st32" width="345.7" height="251.7"/>
        <foreignobject  x="34" y="40" width="338" height="238">
                    <div xmlns="http://www.w3.org/1999/xhtml" >Here is a long text that runs more than one line and works as a paragraph</div>
                    <br />
                    <div>This is <u>UNDER LINE</u> one</div>
                    <br />
                    <div>This is <b>BOLD</b> one</div>
                    <br />
                    <div>This is <i>Italic</i> one</div>
            </foreignobject>
    </g>
        
        
        <g id="accelerator" class="textboxes">
        <rect fill="red" x="28.8" y="33.8" class="st32a" width="345.7" height="251.7"/>
        <foreignobject  x="34" y="40" width="338" height="238">
                    <div xmlns="http://www.w3.org/1999/xhtml" >accelerator BOX of text.</div>
                    <br />
                    <div>This is <u>accelerator BOX of text.</u> one</div>
                    <br />
                    <div>This is <b>accelerator BOX of text.</b> one</div>
                    <br />
                    <div>This is <i>accelerator BOX of text.</i> one</div>
            </foreignobject>
    </g>

Upvotes: 2

Views: 1086

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101956

As per @enxaneta's suggestion, using classes is a little cleaner.

However, you might prefer to use a "hidden" class rather than one named "visible". Depending on whether your elements are normally visible or hidden. Your choice.

.hidden {
   display: none;
}

Then your code would become

var id = 'name';

function place(id) {
  var gs = document.getElementsByTagName("g");

  // Hide all the elements    
  for (var i = 0; i < gs.length; i++) {
    gs[i].classList.add("hidden");
  }
  // But make sure the one with "id" is visible
  document.getElementById(id).classList.remove("hidden");
}

Working demo

function place(id) {
  var gs = document.getElementsByTagName("g");

  // Hide all the elements    
  for (var i = 0; i < gs.length; i++) {
    gs[i].classList.add("hidden");
  }
  // But make sure the one with "id" is visible
  document.getElementById(id).classList.remove("hidden");
}


function reset() {
  document.querySelectorAll("g").forEach(g => g.classList.remove("hidden"));
}
.hidden {
  display: none;
}
<svg width="400" height="100">
  <g id="one" onclick="place('one')">
    <circle cx="50" cy="50" r="40" fill="red"/>
  </g>
  <g id="two" onclick="place('two')">
    <circle cx="150" cy="50" r="40" fill="orange"/>
  </g>
  <g id="three" onclick="place('three')">
    <circle cx="250" cy="50" r="40" fill="gold"/>
  </g>
  <g id="four" onclick="place('four')">
    <circle cx="350" cy="50" r="40" fill="green"/>
  </g>
</svg>


<br/>
<button type="button" onclick="reset()">Reset circles</button>

Upvotes: 2

Related Questions