¿Cómo puedo forzar a WebKit a redibujar/repintar para propagar cambios de estilo?


Tengo un JavaScript trivial para efectuar un cambio de estilo:

sel = document.getElementById('my_id');
sel.className = sel.className.replace(/item-[1-9]-selected/,'item-1-selected');
return false;

Esto funciona bien con las últimas versiones de FF, Opera e IE, pero falla en las últimas versiones de Chrome y Safari.

Afecta a dos descendientes, que resultan ser hermanos. El primer hermano se actualiza, pero el segundo no. Un hijo del segundo elemento también tiene foco y contiene la etiqueta que contiene el código anterior en un atributo onclick.

En el Cromo Ventana" Herramientas para desarrolladores " si anulo (por ejemplo, desmarca y marca) cualquier atributo de cualquier elemento , el segundo hermano se actualiza al estilo correcto.

¿Existe una solución alternativa para "empujar" WebKit de forma fácil y programática a hacer lo correcto?

Author: danorton, 0000-00-00

3 answers

Encontré algunas sugerencias complicadas y muchas simples que no funcionaron, pero un comentario a una de ellas por Vasil Dinkov proporcionó una solución simple para forzar un redibujo/repintado que funciona bien:

sel.style.display='none';
sel.offsetHeight; // no need to store this anywhere, the reference is enough
sel.style.display='';

Dejaré que alguien más comente si funciona para estilos que no sean "bloque".

Gracias, Vasil!

 286
Author: danorton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-26 16:28:50

Recientemente encontramos esto y descubrimos que la promoción del elemento afectado a una capa compuesta con translateZ en CSS solucionó el problema sin necesidad de JavaScript adicional.

.willnotrender { 
   transform: translateZ(0); 
}

Como estos problemas de pintura aparecen principalmente en Webkit/Blink, y esta corrección se dirige principalmente a Webkit/Blink, es preferible en algunos casos. Especialmente porque la respuesta aceptada casi con certeza causa una reflujo y repintado, no solo un repintar.

Webkit y Blink han estado trabajando duro en el rendimiento de renderizado, y este tipo de fallas son el desafortunado efecto secundario de las optimizaciones que tienen como objetivo reducir los flujos y pinturas innecesarios. CSS cambiará u otra especificación posterior será la solución futura, muy probablemente.

Hay otras formas de lograr una capa compuesta, pero esta es la más común.

 76
Author: morewry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-31 23:11:37

La solución de Danorton no funcionó para mí. Tuve algunos problemas realmente extraños donde webkit no dibujaba algunos elementos en absoluto; donde el texto en las entradas no se actualizaba hasta onblur; y cambiar el nombre de la clase no resultaría en un redibujado.

Mi solución, que descubrí accidentalmente, fue agregar un elemento de estilo vacío al cuerpo, después del script.

<body>
...
<script>doSomethingThatWebkitWillMessUp();</script>
<style></style>
...

Eso lo arregló. ¿Qué tan raro es eso? Espero que esto sea útil para alguien.

 51
Author: ,
Warning: date() expects parameter 2 to be long, string given in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61