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()window.requestAnimationFrame()MutationObserverLo 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.
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); } }); }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>