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

228
Views
Cómo esperar a que appendChild() actualice y aplique estilo al DOM, antes de intentar medir el ancho del nuevo elemento

Estoy agregando un elemento DOM como este:

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

Cuando trato de medir inmediatamente el ancho del nuevo elemento, obtengo 2 .

Lo intenté:

  • setTimeout()
  • ventana anidada window.requestAnimationFrame()
  • MutationObserver

Lo anterior funciona de manera muy poco confiable, como el 50% del tiempo. Solo cuando configuré un tiempo de espera grande como 500 ms, funcionó.

Esto sucede solo en el móvil.

Esta es la solución que estoy usando, pero es fea:

 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)) }

Probé con ambas funciones getWidthFromStyle() y getWidthFromBoundingClientRect() - sin diferencia. El ancho se calcula correctamente después de un par de ciclos.

También intenté usar MutationObserver sin éxito.

¿Hay alguna manera de saber cuándo el DOM está completamente actualizado y diseñado antes de intentar medir el ancho/alto de un elemento?

PD: no estoy usando ningún marco. this.store.state.runtime... es mi propia implementación de una tienda, similar a Vue.

EDITAR: El tamaño del elemento dependía de una imagen dentro de él y estaba tratando de medir el elemento antes de que se cargara la imagen. Tonto.

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

0

Puedes usar algo como esto:

 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 Report

0

se puede hacer con MutationObserver .
¿Este método no resuelve tu problema?

 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 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!