javascript – Swapping SVG element color back and forth on click

Question:

This question has been asked many times and there are good solutions using javascript , like this:

var shapeClick = document.getElementById("shape").addEventListener("click", changeColor);
var clicks = 0;
function changeColor(){
  if (shape.style.fill == "rgb(29, 172, 249)")
  {
    shape.style.fill = "rgb(255, 0, 0)";
  }
  else {
    shape.style.fill = "rgb(29, 172, 249)";
  }
}
<div>  
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
 width="250" height="250" viewBox="0 0 250 250" 
> 
         <circle id="shape" class="seat" cx="120" cy="125" r="50" style="fill: #1dacf9" stroke="black" stroke-width="2" />>
 
   </svg> 
   </div>

Everything works fine, with the help of scripts you can do a lot.

Attention question

How to do the same on pure SVG (SMIL) without using javascript and CSS .

Just changing the color on click is easy:

<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
 width="250" height="250" viewBox="0 0 250 250" 
> 
         <circle  cx="120" cy="125" r="50" style="fill: dodgerblue; stroke:black; stroke-width:2;" >
		 <animate attributeName="fill" from="dodgerblue" to="red" fill="freeze" begin="svg1.click" dur="0.1s" calcMode="discrete"/>
			 </circle>
	 
   </svg> 

But how to change the color back by clicking on the object again does not occur to me.

Answer:

if (shape.style.fill == "rgb(29, 172, 249)")

So it's better not to. And then someone will return 1DACF9 instead of rgb(29, 172, 249) and that's it.

How to do the same on pure SVG, SMIL without using – javascript, CSS

label {
  display: block;
}

#red {
  display: none;
}

svg {
  width: 250px;
  display: block;
}

#shape {
  fill: green;
  stroke: black;
  stroke-width: 2;
}

#red:checked + svg #shape {
  fill: red;
}
<label>  
  <input type=checkbox id=red>
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250"> 
    <circle id="shape" class="seat" cx="120" cy="125" r="50" />
  </svg> 
</label>

where and how is the click on the element handled?

The example above resulted in a click on the entire svg .
To fix this, you can use pointer-events .

label {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

#red {
  display: none;
}

svg {
  width: 250px;
  display: block;
}

foreignObject svg {
  pointer-events: none;
}

#shape {
  fill: green;
  stroke: black;
  stroke-width: 2;
  pointer-events: all;
}

#red:checked + svg #shape {
  fill: red;
}
<label>
  <input type=checkbox id=red>
  <svg viewBox="0 0 250 250">
    <circle id="shape" class="seat" cx="120" cy="125" r="50" />
  </svg>
</label>

If you need to place several such objects inside one svg, you can use foreignObject , however, it should be noted that its support by browsers is very doubtful .

label {
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

#red {
  display: none;
}

svg {
  width: 250px;
  display: block;
}

foreignObject svg {
  pointer-events: none;
}

#shape {
  fill: green;
  stroke: black;
  stroke-width: 2;
  pointer-events: all;
}

#red:checked + svg #shape {
  fill: red;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
  <rect x="0" y="0" width="100%" height="125" fill="silver" />
  <foreignObject x="0" y="0" width="100%" height="100%">
    <label xmlns="http://www.w3.org/1999/xhtml">
      <input type=checkbox id=red>
      <svg viewBox="0 0 250 250">
        <circle id="shape" class="seat" cx="120" cy="125" r="50" />
      </svg>
    </label>
  </foreignObject>
</svg>
Scroll to Top