Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

231
Views
Inline SVG Styles Respond when not using groups, but become unresponsive with groups

I'm using Javascript to dynamically create a SVG element composed of several shapes. The objects are being created dynamically such as done in this fiddle

The onclick function call should change the fill from yellow to black and back, and though it seems straightforward, of course it isn't :)

function toggleFill() {
  let w = document.getElementById("svgCircle1");
  //let isYellow = w.getAttribute('fill') == 'yellow';
  let isYellow = w.style.fill == 'yellow';

  console.log("w> " + w);
  console.log("fill> " + w.style.fill);

  if (isYellow) {
    //w.setAttribute('fill', 'black');
    w.style.fill = "black";
  } else {
    //w.setAttribute('fill', 'yellow');
    w.style.fill = "yellow";
  }
}

function doDrawing(x, y, r) {
  const svgNS = "http://www.w3.org/2000/svg";
  let svg = document.querySelector("svg");

  function drawCircle(cx, cy, r) {
    let c = document.createElementNS(svgNS, "circle");
    c.setAttribute("id", "svgCircle1");
    c.setAttribute("class", "svgCircle");
    c.setAttribute("cx", cx);
    c.setAttribute("cy", cy);
    c.setAttribute("r", r);
    c.setAttribute("onclick", "toggleFill();");
    return c;
  }

  g = document.createElementNS(svgNS, "g");
  g.setAttribute("id", "svgG1");
  g.appendChild(drawCircle(x, y, r));

  svg.appendChild(g);
}
.svgCircle {
  fill: yellow;
}
<button id="button1" onclick="doDrawing( 50, 50, 10 );">Draw</button>

<svg width="1000" height="400" id="drawing">
</svg>

The issue is that sometimes the style attribute will be empty, sometimes it will have the correct value and not update, and some rare times it will work.

If I remove the group, it executes correctly. I see the same behaviour with the style.fill attribute access as I do with the getAttribute method call.

I had thought that perhaps the class style was being reapplied to the object for some unbeknownst reason, but adding the classList.remove has not resolved the issue either.

I can work around this issue by inverting the if logic and using my knowledge of the initial color, then setting the variable to black if it fails to match. Once the initial JS setAttribute or style.fill is run, then code becomes reliable.

I'm certain there's something basic I've overlooked, I'd prefer to understand what I missed than rely on the work around.

In the event it's relevant I've been testing in Chrome.

Thanks!

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You need to stick to one way of adding the fill -- either as an attribute or in CSS.

I also removed the id. Now I don't know the use case, but ids have to be unique and you where pointing to a specific id in your function. So, here I just have an event listener for the entire SVG.

document.querySelector("svg").addEventListener('click', e => {
  let w = e.target;
  if (w.nodeName == 'circle') {
    let isYellow = w.style.fill == 'yellow';

    console.log("w> " + w);
    console.log("fill> " + w.style.fill);

    if (isYellow) {
      //w.setAttribute('fill', 'black');
      w.style.fill = "black";
    } else {
      //w.setAttribute('fill', 'yellow');
      w.style.fill = "yellow";
    }
  }
});

function doDrawing(x, y, r) {
  const svgNS = "http://www.w3.org/2000/svg";
  let svg = document.querySelector("svg");

  function drawCircle(cx, cy, r) {
    let c = document.createElementNS(svgNS, "circle");
    c.setAttribute("class", "svgCircle");
    c.setAttribute("cx", cx);
    c.setAttribute("cy", cy);
    c.setAttribute("r", r);
    c.style.fill = "yellow";
    return c;
  }

  g = document.createElementNS(svgNS, "g");
  g.setAttribute("id", "svgG1");
  g.appendChild(drawCircle(x, y, r));

  svg.appendChild(g);
}
<button id="button1" onclick="doDrawing( 50, 50, 10 );">Draw</button>
<svg width="1000" height="400" id="drawing">
</svg>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!