Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

234
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda