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

242
Visualizações
How to wait for appendChild() to update and style the DOM, before trying to measure the new element's width

I'm appending a DOM element like this:

this.store.state.runtime.UIWrap.appendChild(newElement)

When I immediately try to measure the new element's width I get 2.

I tried:

  • setTimeout()
  • double nested window.requestAnimationFrame()
  • MutationObserver

The above works very unreliably, like 50% of the time. Only when I set a large timeout like 500ms it worked.

This happens only on mobile.

This is the workaround that I'm using, but it's ugly:

function getWidthFromStyle(el) {
  return parseFloat(getComputedStyle(el, null).width.replace('px', ''))
}
function getWidthFromBoundingClientRect(el) {
  return el.getBoundingClientRect().width
}

console.log(getWidthFromBoundingClientRect(newElement))

while (getWidthFromBoundingClientRect(newElement) < 50) {
  await new Promise(r => setTimeout(r, 500))
  console.log(getWidthFromBoundingClientRect(newElement))
}

I tried with both functions getWidthFromStyle() and getWidthFromBoundingClientRect() - no difference. The width gets calculated properly after a couple of cycles.

I also tried using MutationObserver without success.

Is there a way to know when the DOM is fully updated and styled before I try to measure an element's width/height?

P.S. I'm not using any framework. this.store.state.runtime... is my own implementation of a Store, similar to Vue.

EDIT: The size of the element depended on an image inside it and I was trying to measure the element before the image had loaded. Silly.

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

You can use something like this:

export function waitElement(elementId) {
  return new Promise((resolve, reject) => {
    const element = document.getElementById(elementId);
    if (element) {
      resolve(element);
    } else {
      let tries = 10;
      const interval = setInterval(() => {
        const element = document.getElementById(elementId);
        if (element) {
          clearInterval(interval);
          resolve(element);
        }
        if (tries-- < 0) {
          clearInterval(interval);
          reject(new Error("Element not found"));
        }
      }, 100);
    }
  });
}
about 4 years ago · Juan Pablo Isaza Relatório

0

it can done with MutationObserver.
doesn't this method solve your problem?

const div = document.querySelector("div");
const span = document.querySelector("span");

const observer = new MutationObserver(function () {
  console.log("new width", size());
});

observer.observe(div, { subtree: true, childList: true });

function addElem() {
  setTimeout(() => {
    const newSpan = document.createElement("span");
    newSpan.innerHTML = "second";
    div.appendChild(newSpan);
    console.log("element added");
  }, 3000);
}

function size() {
  return div.getBoundingClientRect().width;
}

console.log("old width", size());
addElem();
div {
  display: inline-block;
  border: 1px dashed;
}
span {
  background: gold;
}
<div>
  <span>one</span>
</div>

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