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 elemento secundario del segundo elemento también tiene foco y contiene la etiqueta <a> que contiene el código anterior en un atributo onclick .
En la ventana "Herramientas para desarrolladores" de Chrome, si empujo (por ejemplo, desmarco y verifico) cualquier atributo de cualquier elemento, el segundo hermano se actualiza al estilo correcto.
¿Existe una solución para "empujar" WebKit de manera fácil y programática para que haga lo correcto?
css
google-chrome
safari
webkit
Danorton
fuente
fuente
Respuestas:
Encontré algunas sugerencias complicadas y muchas simples que no funcionaron, pero un comentario de Vasil Dinkov a una de ellas me proporcionó una solución simple para forzar un nuevo dibujo / repintado que funciona bien:
Dejaré que alguien más comente si funciona para otros estilos que no sean "bloque".
Gracias Vasil!
fuente
'inline-block'
,'table'
o en'run-in'
lugar de hacerlo'none'
, pero esto puede tener efectos secundarios. Además, un tiempo de espera de 0 desencadena un reflujo al igual que las consultasoffsetHeight
:sel.style.display = 'run-in'; setTimeout(function () { sel.style.display = 'block'; }, 0);
Recientemente nos encontramos con 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.
Como estos problemas de pintura se muestran principalmente en Webkit / Blink, y esta solución se dirige principalmente a Webkit / Blink, es preferible en algunos casos. Sobre todo porque la respuesta aceptada casi con certeza causa un reflujo y repintado , no solo un repintado.
Webkit y Blink han estado trabajando arduamente en el rendimiento del renderizado, y este tipo de fallas son el desafortunado efecto secundario de las optimizaciones que apuntan a reducir 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.
fuente
La solución de Danorton no funcionó para mí. Tuve algunos problemas realmente extraños donde webkit no dibujaba algunos elementos; donde el texto en las entradas no se actualizó hasta onblur; y cambiar className no daría lugar a un redibujo.
Descubrí accidentalmente que mi solución fue agregar un elemento de estilo vacío al cuerpo, después del guión.
Eso lo arregló. ¿Qué tan raro es eso? Espero que esto sea útil para alguien.
fuente
var div = $('<div>').appendTo(element); setTimeout(function(){ div.remove(); }, 0);
$('<style></style>').appendTo($(document.body)).remove();
Como el disparador display + offset no funcionó para mí, encontré una solución aquí:
http://mir.aculo.us/2009/09/25/force-redraw-dom-technique-for-webkit-based-browsers/
es decir
fuente
scale(1)
, me lo asigné a sí mismo comoelement.style.webkitTransform = element.style.webkitTransform
. ¡La razón de esto es que establecerlo en el primero estaba distorsionando ligeramente la página paraabsolute
elementos posicionados correctamente!display
tenía la solución.Estaba sufriendo el mismo problema. La corrección de 'pantalla de alternancia' de danorton funcionó para mí cuando se agregó a la función de paso de mi animación, pero estaba preocupado por el rendimiento y busqué otras opciones.
En mi circunstancia, el elemento que no se estaba repintando estaba dentro de un elemento de posición absoluta que, en ese momento, no tenía un índice z. Agregar un índice z a este elemento cambió el comportamiento de Chrome y los repintes ocurrieron como se esperaba -> las animaciones se suavizaron.
Dudo que esto sea una panacea, imagino que depende de por qué Chrome ha elegido no volver a dibujar el elemento, pero estoy publicando esta solución específica aquí en la ayuda que espera que alguien.
Saludos, Rob
tl; dr >> Intente agregar un índice z al elemento o uno de sus padres.
fuente
Los siguientes trabajos. Solo debe configurarse una vez en CSS puro. Y funciona de manera más confiable que una función JS. El rendimiento parece no verse afectado.
fuente
zoom
lugar de relleno:@-webkit-keyframes safariBugFix {from { zoom: 100%; } to { zoom: 99.99999%; }}
Por alguna razón no pude obtener la respuesta de danorton para trabajar, pude ver lo que se suponía que debía hacer, así que modifiqué un poco esto:
Y funcionó para mí.
fuente
Vine aquí porque necesitaba volver a dibujar las barras de desplazamiento en Chrome después de cambiar su CSS.
Si alguien tiene el mismo problema, lo resolví llamando a esta función:
Este método no es la mejor solución, pero puede funcionar con todo, ocultar y mostrar el elemento que necesita ser redibujado puede resolver todos los problemas.
Aquí está el violín donde lo usé: http://jsfiddle.net/promatik/wZwJz/18/
fuente
Me encontré con esto hoy: Element.redraw () para prototype.js
Utilizando:
Sin embargo, a veces he notado que debe llamar a redraw () en el elemento problemático directamente. A veces, volver a dibujar el elemento padre no resolverá el problema que está experimentando el niño.
Buen artículo sobre la forma en que los navegadores procesan elementos: Renderizado: repintado, reflujo / retransmisión, restyle
fuente
appendChild
es un método DOM, no un método jQuery.Tuve este problema con un número de divs que se insertaron en otro div con
position: absolute
, los div insertados no tenían atributo de posición. Cuando cambié estoposition:relative
, funcionó bien. (Fue realmente difícil determinar el problema)En mi caso los elementos fueron insertados por Angular con
ng-repeat
.fuente
No puedo creer que esto siga siendo un problema en 2014. Acabo de tener este problema al actualizar un cuadro de subtítulos de posición fija en la parte inferior izquierda de la página mientras se desplazaba, el subtítulo se 'fantasma' en la pantalla. Después de probar todo lo anterior sin éxito, noté que muchas cosas eran lentas / causaban problemas debido a la creación de retransmisiones DOM muy cortas, etc., lo que provocaba un desplazamiento de sensación algo poco natural, etc.
Terminé haciendo una posición fija, div de tamaño completo
pointer-events: none
y aplicando la respuesta de danorton a ese elemento, lo que parece forzar un redibujo en toda la pantalla sin interferir con el DOM.HTML:
CSS:
JS:
fuente
z-index
ypointer-events
son superfluas aquí.No es que esta pregunta necesite otra respuesta, pero descubrí que simplemente cambiar el color un poco obligó a volver a pintar en mi situación particular.
El
setTimeout
resultado crítico para mover el segundo cambio de estilo fuera del ciclo de eventos actual.fuente
La única solución que funciona para mí es similar a la respuesta de sowasred2012:
Tengo muchos bloques de problemas en la página, por lo que cambio la
display
propiedad del elemento raíz. Y lo uso endisplay: table;
lugar dedisplay: none;
, porquenone
restablecerá el desplazamiento de desplazamiento.fuente
Yo uso el
transform: translateZ(0);
método pero en algunos casos no es suficiente.No soy fanático de agregar y eliminar una clase, así que intenté encontrar la manera de resolver esto y terminé con un nuevo truco que funciona bien:
fuente
Como todos parecen tener sus propios problemas y soluciones, pensé que agregaría algo que funcione para mí. En Android 4.1 con Chrome actual, tratando de arrastrar un lienzo dentro de un div con desbordamiento: oculto, no pude volver a dibujar a menos que agregue un elemento al div padre (donde no haría ningún daño).
Sin parpadeo de pantalla o actualización real, y limpiando después de mí. No hay variables globales o de ámbito de clase, solo locales. No parece dañar nada en Mobile Safari / iPad o navegadores de escritorio.
fuente
Estoy trabajando en la aplicación iónica html5, en pocas pantallas he
absolute
colocado el elemento, cuando me desplazo hacia arriba o hacia abajo en dispositivos IOS (iPhone 4,5,6, 6+) tuve un error de repintado.Intenté muchas soluciones, ninguna de ellas funcionaba, excepto que esta resolvió mi problema.
He usado la clase CSS
.fixRepaint
en esos elementos de posiciones absolutasEsto ha solucionado mi problema, puede ser útil para alguien
fuente
Esto está bien para JS
Pero en Jquery, y particularmente cuando solo puede usar $ (document) .ready y no puede vincularse a un evento .load de un objeto por alguna razón en particular, lo siguiente funcionará.
Debe obtener el contenedor OUTER (MOST) de los objetos / divs y luego eliminar todo su contenido en una variable, luego volver a agregarlo. Hará visibles TODOS los cambios realizados dentro del contenedor externo.
fuente
Este método me ha resultado útil al trabajar con transiciones.
fuente
El truco "display / offsetHeight" no funcionó en mi caso, al menos cuando se aplicó al elemento que se estaba animando.
Tenía un menú desplegable que estaba siendo abierto / cerrado sobre el contenido de la página. los artefactos se dejaron en el contenido de la página después de que se cerró el menú (solo en los navegadores webkit). la única forma en que funcionó el truco "display / offsetHeight" es si lo apliqué al cuerpo, lo que parece desagradable.
Sin embargo, encontré otra solución:
Esto sigue siendo bastante hacky (usa una propiedad CSS3 para forzar la representación del hardware), pero al menos solo afecta el elemento en cuestión, y funcionó para mí tanto en Safari como en Chrome en PC y Mac.
fuente
Esto parece relacionado con esto: estilo jQuery no se aplica en Safari
La solución sugerida en la primera respuesta me ha funcionado bien en estos escenarios, a saber: aplicar y eliminar una clase ficticia al cuerpo después de realizar los cambios de estilo:
Esto obliga al safari a volver a dibujar.
fuente
las sugerencias anteriores no funcionaron para mí. pero el de abajo sí.
Quiere cambiar el texto dentro del ancla dinámicamente. La palabra "Buscar". Creó una etiqueta interna "fuente" con un atributo de identificación. Gestioné los contenidos usando javascript (abajo)
contenido del guión:
fuente
Estaba teniendo un problema con un SVG que estaba desapareciendo en Chrome para Android cuando se cambió la orientación en ciertas circunstancias. El siguiente código no lo reproduce, pero es la configuración que teníamos.
Día y medio después, después de pinchar y pinchar y no estar contento con las soluciones hacky que se ofrecen aquí, descubrí que el problema fue causado por el hecho de que parecía mantener el elemento en la memoria mientras dibujaba uno nuevo. La solución fue hacer que la ID del linealGradient en el SVG sea única, a pesar de que solo se usó una vez por página.
Esto se puede lograr de muchas maneras diferentes, pero para nuestra aplicación angular utilizamos la función lodash uniqueId para agregar una variable al alcance:
Directiva angular (JS):
Actualizaciones HTML:
Línea 5:
<linearGradient ng-attr-id="{{indicatorColourPatternId}}" x1="0" x2="0" y1="0" y2="1">
Línea 11:
<rect x="0" y="0" rx="5" ry="5" width="100%" height="100%" ng-attr-fill="url(#{{indicatorColourPatternId}})"/>
Espero que esta respuesta le ahorre a alguien más un día para destrozar su teclado.
fuente
Recomendaría una forma menos hackea y más formal de forzar un reflujo: use forceDOMReflowJS . En su caso, su código se vería de la siguiente manera.
fuente
Descubrí que solo agregar un estilo de contenido al elemento lo obligaba a volver a pintar, este debería ser un valor diferente cada vez que desea volver a dibujar y no necesita estar en un pseudo elemento.
fuente
Intenté una respuesta más irónica pero no me funciona. Tuve problemas para tener el mismo ancho de cliente con safari en comparación con otros navegadores y este código resolvió el problema:
Es realmente extraño porque si intento nuevamente obtener el ancho de cliente después de get_safe_value, obtengo un mal valor con safari, el getter debe estar entre
sty.transform = "translateZ(1px)";
ysty.transform = "";
La otra solución que funciona definitivamente es
El problema es que pierdes el foco y los estados de desplazamiento.
fuente
Esto forzará el repintado mientras evita el parpadeo, los ajustes de elementos existentes y cualquier problema de diseño ...
fuente
Una solución simple con jquery:
o
Tenía un SVG que no se mostraba cuando se agregaba al html.
Esto se puede agregar después de que los elementos svg estén en la pantalla.
La mejor solución es usar:
y con jQuery:
Esto se representará correctamente en Chrome.
fuente