El desplazamiento del iPad Safari hace que los elementos HTML desaparezcan y reaparezcan con retraso

165

Actualmente estoy desarrollando una aplicación web usando html5 y jQuery para iPad Safari. Me encuentro con un problema en el que grandes áreas de desplazamiento hacen que los elementos que están fuera de la pantalla aparezcan después de un retraso cuando me desplazo hacia ellos.

Lo que quiero decir con eso es que si tengo una fila de imágenes (o incluso un div con un degradado) que está fuera de la pantalla, cuando me desplazo hacia abajo (o hacia arriba), el comportamiento esperado es que el elemento aparezca en la pantalla como Me estoy desplazando a eso.

Sin embargo, lo que veo es que el elemento no aparece hasta que levanto el dedo de la pantalla y el desplazador finaliza todas sus animaciones.

Esto me está causando un problema súper notable, haciendo que todo parezca entrecortado, aunque no lo es. Supongo que el iPad Safari está tratando de hacer algo para ahorrar memoria. ¿Hay alguna manera de evitar que ocurra esta agitación? Además, también agradecería si alguien puede arrojar luz sobre lo que el iPad Safari realmente está tratando de hacer.

codeBearer
fuente
Este problema / solución me ayudó a solucionar un problema con la versión jPanelMenu 1.3 CSS Transforms, que convirtió todo en mi sitio invisible hasta que agregué el fragmento anterior.
75th Trombone
2
El uso de *: not (html) aplicará el translate3d a todos los demás aspectos de su sitio y no lo recomiendo. Causará que las imágenes en pestañas desaparezcan a medida que se desplaza hacia abajo, etc., los errores que podría estar acostumbrado a ver solo en sus imágenes en 3D ahora estarán presentes en otros aspectos de su sitio.
Jonathan Tonge
1
Tenía algunos <svg>elementos que exhibían un dibujo / renderizado retrasado similar. Desafortunadamente, *:not(html) { ... }condujo a todo tipo de comportamientos extraños, como señaló @JonathanTonge que podría ocurrir. Sin embargo, seleccionar solo los <svg>elementos y usarlos translate3d(0, 0, 0,);parece haber resuelto mis problemas de desplazamiento.
Zephyr Mays
Excepto en casos de uso muy específicos, esto es basura. Realmente desordena los diseños que dependen de elementos de posición absoluta.
Stoutie
2
Publique las respuestas como respuestas, no "EDITAR" en su pregunta. Sé que te gusta más tu respuesta, y eso está bien, pero StackOverflow tiene un formato de preguntas y respuestas que funciona mejor cuando las Q son distintas de las A.
Slipp D. Thompson

Respuestas:

184

Debe engañar al navegador para que use la aceleración de hardware de manera más efectiva. Puede hacer esto con una transformación 3d vacía:

-webkit-transform: translate3d(0,0,0)

En particular, necesitará esto en los elementos secundarios que tienen una position:relative;declaración (o, simplemente, haga todo lo posible y hágalo en todos los elementos secundarios).

No es una solución garantizada, pero es bastante exitosa la mayor parte del tiempo.

Punta de sombrero: https://web.archive.org/web/20131005175118/http://cantina.co/2012/03/06/ios-5-native-scrolling-grins-and-gothcas/

Colin Williams
fuente
3
También probé eso. Lamentablemente, agregar un translate3d es cortar elementos que se mostraban correctamente antes. También necesitaba aceleración de hardware para un par de objetos que estaban fuera de la pantalla y tenían que ser animados para "volar" en la pantalla. Estaba usando jQuery's animate (), que era súper lento. Me cambié a usar la aceleración de hardware. Aunque eso aceleró la animación, produjo resultados erráticos, en el sentido de que algunos de los elementos secundarios del elemento primario (animación) se cortaron. Esto no estaba sucediendo cuando estaba usando animate ().
codeBearer
1
@Colin Williams, me acabas de alegrar el día. : D
Lucas
9
Wow, eso es horrible pero efectivo. Gracias.
Tim Down
1
¡Hombre de las estrellas de oro! Lo agregué a todos mis elementos li en un div desplazable. Maricón. Trabajó.
Bryan Johnson
68

Esta es la respuesta completa a mi pregunta. Originalmente había marcado la respuesta de @Colin Williams como la respuesta correcta, ya que me ayudó a llegar a la solución completa. Un miembro de la comunidad, @Slipp D. Thompson, editó mi pregunta, después de aproximadamente 2,5 años de haberla preguntado, y me dijo que estaba abusando del formato de preguntas y respuestas de SO. También me dijo que publicara esto por separado como respuesta. Así que aquí está la respuesta completa que resolvió mi problema:

@Colin Williams, gracias! Su respuesta y el artículo al que se vinculó me dieron una pista para probar algo con CSS.

Entonces, estaba usando translate3d antes. Produjo resultados no deseados. Básicamente, cortaría y NO RENDERÍA elementos que estaban fuera de pantalla, hasta que interactué con ellos. Entonces, básicamente, en orientación horizontal, la mitad de mi sitio que estaba fuera de la pantalla no se mostraba. Esta es una aplicación web para iPad, por lo que estaba en una solución.

La aplicación de translate3d a elementos relativamente posicionados resolvió el problema para esos elementos, pero otros elementos dejaron de renderizarse, una vez fuera de la pantalla. Los elementos con los que no podía interactuar (ilustraciones) nunca volverían a mostrarse, a menos que volviera a cargar la página.

La solución completa:

*:not(html) {
    -webkit-transform: translate3d(0, 0, 0);
}

Ahora, aunque esta podría no ser la solución más "eficiente", fue la única que funciona. Mobile Safari no procesa los elementos que están fuera de la pantalla, o a veces se procesa de manera irregular, cuando se usa -webkit-overflow-scrolling: touch. A menos que se aplique un translate3d a todos los demás elementos que podrían salir de la pantalla debido a ese desplazamiento, esos elementos se cortarán después del desplazamiento.

Entonces, gracias de nuevo, y espero que esto ayude a alguna otra alma perdida. ¡Esto seguramente me ayudó a lo grande!

codeBearer
fuente
2
Guau. Gracias por esto. Me ahorró una gran cantidad de dolor de cabeza para mi aplicación phonegap / cordova. En mi caso tuve que cambiar *:not(html)abody *
anon
9
solo aplicarme -webkit-transform: translate3d(0, 0, 0);al elemento problema me funcionó. En mi caso estaba usando ScrollMagic
fidev
Nada de esto funcionó para mí tampoco. Tan pronto como me desplazo hacia abajo hasta cierto punto, las cosas que ya no son visibles por encima de la ventana se combinan, así como algunos elementos en la ventana gráfica. Noto una "sacudida" muy leve pero inconfundible mientras se desplaza, después de lo cual los elementos se manguean. (Es decir: suave - nervioso - comportamiento suave, como si tuviera hipo durante el desplazamiento). Esto está en iPad.
cbmtrx
Por cierto, acabo de descubrir que en un iPad Air 2, cuando un elemento en pantalla específico (una barra de navegación, en este caso) se sale de la pantalla, el dispositivo "recarga" ese bloque, solo usando la versión grande, no la mediana original que la página cargó con. What the ...
cbmtrx
En caso de que alguien experimente la misma rareza que yo, un poco diferente de lo que se describe en esta página, descubrí que usar en $(window).width()lugar de window.innerWidthjQuery marcó la diferencia para iOS. Quién sabe.
cbmtrx
13

Apuntar a todos los elementos excepto html: *:not(html) en mi caso, causé problemas en otros elementos. Modificó el contexto de apilamiento, haciendo que se rompa algún índice z.

Deberíamos tratar de apuntar al elemento correcto y aplicarlo -webkit-transform: translate3d(0,0,0)solo a él.

Editar: a veces translate3D(0,0,0)no funciona, podemos usar el siguiente método, apuntando al elemento correcto:

@keyframes redraw{
    0% {opacity: 1;}
    100% {opacity: .99;}
}

// ios redraw fix
animation: redraw 1s linear infinite;
Guillaume Gautier
fuente
Estaba enfrentando el mismo problema. Puede usar el body *selector en lugar de *:not(html). Resolverá tu problema.
kunal
Felicitaciones por la sugerencia de apuntar a los elementos correctos en lugar de contaminar todo con el *
Maciek Rek
7

Cuando el translate3d no funciona, intente agregar perspectiva. Siempre funciona para mi

transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;

http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css

Fellipe Lima
fuente
Holy C $ # @ finalmente una solución para angular / iónico. -webkit-perspective: 1000;
lilbiscuit
Ahh me salvó el día. +1 para ti;)
Omar Bahir
Esto hizo que mi navegador iOS fallara.
Andreas Richter
-webkit-perspective: 1000;lo hice por mí - gracias
jHilscher
2

Agregar -webkit-transform: translate3d(0,0,0)a un elemento estáticamente no funciona para mí.

Aplico esta propiedad dinámicamente. Por ejemplo, cuando se desplaza una página, configuro -webkit-transform: translate3d(0,0,0)un elemento. Luego, después de un breve retraso, restablezco esta propiedad, es decir, -webkit-transform: none este enfoque parece funcionar.

Gracias, @Colin Williams por señalarme en la dirección correcta.

Alexander Poleschuk
fuente
Esta pista me ayudó mucho, ya que estos estilos tienen algunos efectos secundarios no deseados, por lo general quiero evitarlos. Por lo tanto, uso los eventos touchstart / touchend para agregarlos y eliminarlos. ¡Gracias!
Windwalker
1

Tuve el mismo problema con iscroll 4.2.5 en ios7. Todo el elemento de desplazamiento simplemente desaparece. Intenté agregar translate3d(0,0,0)como se sugirió aquí, resolvió el problema, pero deshabilitó el efecto de "ajuste" de iscroll. La solución vino con dar "position:relative; z-index:1000;display:block"propiedades css a todo el contenedor que contiene el elemento de desplazamiento y no hay necesidad de dar translate3d a elementos secundarios.

yudarik
fuente
Utilicé esta técnica para resolver un problema similar en Android Chrome. El desplazamiento vertical parecía funcionar mejor que cuando probé la corrección translate3d. En mi caso, el <body>elemento es lo que utilicé para el desplazamiento y funcionó una versión simplificada:body { position: relative; z-index: 0; }
BumbleB2na
1

A veces translate3dpuede no funcionar, en esos casos perspectivese puede utilizar

transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
perspective: 1000;
-webkit-perspective: 1000;
Nidhin Joseph
fuente
0

Estoy bastante seguro de que acabo de resolver esto con:

overflow-y: auto;

(Presumiblemente overflow: auto;, también funcionaría dependiendo de sus necesidades).

David Notik
fuente
No hizo nada para mí, mientras que la respuesta aceptada probablemente lo hizo en un escenario diferente
Tony el
0

Hay casos en los que se aplica una rotación y / o se usa un índice Z.

Rotación : una declaración existente de -webkit-transformrotar un elemento podría no ser suficiente para abordar el problema de apariencia también (como -webkit-transform: rotate(-45deg)). En este caso, puede usarlo -webkit-transform: translateZ(0px) rotateZ(-45deg)como un truco ( tenga en cuenta la rotación Z ).

Índice Z : junto con la rotación, puede definir una z-indexpropiedad positiva , como z-index: 42. Los pasos anteriores descritos en "Rotación" fueron en mi caso suficientes para resolver el problema, incluso con el vacío translateZ(0px). Sin embargo, sospecho que el índice Z en este caso puede haber causado la desaparición y reaparición en primer lugar. En cualquier caso, la z-index: 42propiedad debe mantenerse, -webkit-transform: translateZ(42px)solo que no es suficiente.

Stefan Zurfluh
fuente
0

Este es un problema muy común que enfrentan los desarrolladores y que se debe principalmente a la Safari'spropiedad de no recrear elementos definidos como position : fixed.

Entonces, cambie la propiedad de posición o se debe aplicar algún truco como se menciona en otras respuestas.

Enlace1

Link2

arqam
fuente
0

En mi caso (una aplicación iOS Phonegap), la aplicación de translate3d a elementos secundarios relativos no resolvió el problema. Mi elemento desplazable no tenía una altura establecida, ya que estaba absolutamente posicionado y estaba definiendo las posiciones superior e inferior. Lo que me arregló fue agregar una altura mínima (de 100 px).

b4tch
fuente
0

Tuve el mismo problema al usar una versión anterior de Fancybox. Actualizar a v3 resolverá su problema O simplemente puede agregar:

html, body {
    -webkit-overflow-scrolling : touch !important;
    overflow: auto !important;
    height: 100% !important;
}
Adam Touhou
fuente
0

Enfrenté este problema en un proyecto de Framework7 y Cordova. Probé todas las soluciones anteriores. No resolvieron mi problema.

En mi caso, estaba usando más de 10 animaciones CSS en la misma página con rotación infinita (transformación). Tuve que eliminar las animaciones. Está bien ahora con la falta de algunas características visuales.

Si las soluciones anteriores no le ayudan, puede comenzar a eliminar algunas animaciones.

yavuzkirez
fuente
0

El -webkit-transform: translate3d(0, 0, 0);truco no me funcionó. En mi caso, había establecido un padre para:

// parent
height: 100vh;

Cambiando eso a:

height: auto;
min-height: 100vh;

Se resolvió el problema en caso de que alguien más se enfrentara a la misma situación.

funador
fuente
0

En mi caso, CSS no solucionó el problema. Noté el problema al usar jQuery para volver a representar un botón.

$("#myButton").html("text")

Prueba esto

$("#myButton").html("<span>text</span>")
Josh Stovall
fuente