Lo scorrimento di iPad Safari fa scomparire e riapparire elementi HTML in ritardo


165

Attualmente sto sviluppando un'app Web usando html5 e jQuery per iPad Safari. Sto riscontrando un problema in cui ampie aree di scorrimento fanno apparire gli elementi fuori dallo schermo dopo un ritardo quando scorro verso il basso.

Quello che intendo con ciò è che se ho una fila di immagini (o anche un div con una sfumatura) che è fuori schermo, quando scorro verso il basso (o verso l'alto), il comportamento previsto è che l'elemento appaia sullo schermo come Lo sto scorrendo.

Tuttavia, quello che vedo è che l'elemento non appare fino a quando non alzo il dito dallo schermo e lo scroller termina tutte le sue animazioni.

Questo sta causando un problema super evidente per me, facendo sembrare tutto incerto, anche se non lo è. Immagino che l'iPad Safari stia provando a fare qualcosa per risparmiare memoria. Esiste un modo in cui posso impedire che questa instabilità si verifichi. Inoltre, apprezzerei anche se qualcuno potesse far luce su ciò che l'iPad Safari sta effettivamente cercando di fare.


Questo problema / soluzione mi ha aiutato a risolvere un problema con la versione CSS Transforms di jPanelMenu 1.3, che ha reso tutto invisibile sul mio sito fino a quando non ho aggiunto lo snippet sopra.
75th Trombone

2
Usando *: not (html) applicherai il translate3d a tutti gli altri aspetti del tuo sito e non lo consiglio. Ciò causerà la scomparsa delle immagini nelle schede mentre scorri verso il basso, ecc., I bug che potresti utilizzare per vedere solo le tue immagini 3d saranno ora presenti in altri aspetti del tuo sito.
Jonathan Tonge,

1
Avevo alcuni <svg>elementi che mostravano simili ritardi di disegno / rendering. Sfortunatamente, ha *:not(html) { ... }portato a tutti i tipi di comportamenti strani, come potrebbe notare @JonathanTonge. Tuttavia, selezionando solo gli <svg>elementi e usando translate3d(0, 0, 0,);sembra aver risolto i miei problemi di scorrimento.
Zephyr Mays

Fatta eccezione per casi d'uso molto specifici, si tratta di immondizia. Incasina davvero i layout che dipendono da elementi di posizione assoluti.
Stoutie,

2
Inserisci le risposte come risposte, non "MODIFICA" nella tua domanda. So che ti piace di più la tua risposta, e va bene, ma StackOverflow ha un formato di domande e risposte che funziona meglio quando le Q sono distinte dalle A.
Slipp D. Thompson,

Risposte:


184

È necessario ingannare il browser per utilizzare l'accelerazione hardware in modo più efficace. Puoi farlo con una trasformazione 3d vuota:

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

In particolare, avrai bisogno di questo su elementi figlio che hanno una position:relative;dichiarazione (o, fai tutto e fallo su tutti gli elementi figlio).

Non una soluzione garantita, ma abbastanza riuscita per la maggior parte del tempo.

Consiglio per il cappello: https://web.archive.org/web/20131005175118/http://cantina.co/2012/03/06/ios-5-native-scrolling-grins-and-gothcas/


3
Ho provato anche quello. Purtroppo, l'aggiunta di un translate3d sta tagliando gli elementi che erano stati visualizzati correttamente prima. Avevo anche bisogno di accelerazione hardware per un paio di oggetti che erano fuori schermo e dovevano essere animati per "volare dentro" sullo schermo. Stavo usando animate () di jQuery, che era super lento. Sono passato all'utilizzo dell'accelerazione hardware. Anche se ciò ha accelerato l'animazione, ha prodotto risultati irregolari, nel senso che alcuni degli elementi figlio del div genitore (animazione) sono stati tagliati. Questo non stava accadendo quando stavo usando animate ().
codeBearer

1
@Colin Williams mi hai appena reso felice! : D
Luca,

9
Wow, è orribile ma efficace. Grazie.
Tim Down,


1
Amico stella d'oro! L'ho aggiunto a tutti i miei elementi li in un div scorrevole. Poof. Lavorato.
Bryan Johnson,

68

Questa è la risposta completa alla mia domanda. Inizialmente avevo contrassegnato la risposta di @Colin Williams come la risposta corretta, poiché mi ha aiutato a raggiungere la soluzione completa. Un membro della comunità, @Slipp D. Thompson, ha modificato la mia domanda, dopo circa 2,5 anni che l'ho fatta e mi ha detto che stavo abusando del formato di domande e risposte di SO. Mi ha anche detto di pubblicare separatamente questo come risposta. Quindi, ecco la risposta completa che ha risolto il mio problema:

@Colin Williams, grazie! La tua risposta e l'articolo a cui hai collegato mi hanno dato un indizio per provare qualcosa con i CSS.

Quindi, stavo usando translate3d prima. Ha prodotto risultati indesiderati. Fondamentalmente, taglierebbe e NON RENDERÀ gli elementi che erano fuori schermo, fino a quando non interagissi con loro. Quindi, fondamentalmente, in orientamento orizzontale, metà del mio sito che era fuori schermo non veniva mostrato. Questa è un'app Web per iPad, a causa della quale ero in una correzione.

L'applicazione di translate3d ad elementi posizionati relativamente ha risolto il problema per quegli elementi, ma altri elementi hanno interrotto il rendering, una volta fuori dallo schermo. Gli elementi con cui non potrei interagire (grafica) non verranno mai più visualizzati, a meno che non ricarichi la pagina.

La soluzione completa:

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

Ora, sebbene questa potrebbe non essere la soluzione più "efficiente", è stata l'unica a funzionare. Mobile Safari non esegue il rendering degli elementi che sono fuori schermo, o talvolta vengono visualizzati in modo irregolare, durante l'utilizzo -webkit-overflow-scrolling: touch. A meno che un translate3d non venga applicato a tutti gli altri elementi che potrebbero fuoriuscire dallo schermo a causa di tale scorrimento, tali elementi verranno tagliati dopo lo scorrimento.

Quindi, grazie ancora, e spero che questo aiuti qualche altra anima perduta. Questo sicuramente mi ha aiutato alla grande!


2
Wow. Grazie per questo. Mi ha fatto risparmiare un sacco di mal di testa per la mia app phonegap / cordova. Nel mio caso ho dovuto cambiare *:not(html)abody *
anon

9
solo applicando -webkit-transform: translate3d(0, 0, 0);all'elemento problematico ha funzionato per me. Nel mio caso stavo usando ScrollMagic
fidev il

Niente di tutto questo ha funzionato neanche per me. Non appena scorro verso il basso fino a un certo punto, le cose non più visibili sopra la finestra vengono mungute, così come alcuni elementi nella finestra. Noto una "scossa" leggerissima ma inconfondibile mentre scorre, dopo di che gli elementi vengono colmati. (Vale a dire: liscio - nervoso - comportamento regolare, come se fosse un singhiozzo durante lo scorrimento.) Questo è su iPad.
cbmtrx,

A proposito, ho appena scoperto che su un iPad Air 2, quando un elemento sullo schermo specifico (una barra di navigazione, in questo caso) scompare dallo schermo, il dispositivo "ricarica" ​​quel blocco - usando solo la versione grande, non quella media originale con cui è stata caricata la pagina. What the ...
cbmtrx,

Nel caso in cui qualcuno stia vivendo la stessa stranezza di me - leggermente diversa da quella descritta in questa pagina - ho scoperto che l'utilizzo al $(window).width()posto di window.innerWidthin jQuery ha fatto la differenza per iOS. Chissà.
cbmtrx,

13

Targeting per tutti gli elementi tranne HTML: *:not(html) nel mio caso ha causato problemi su altri elementi. Ha modificato il contesto di impilamento, causando l'interruzione di alcuni z-index.

Dovremmo cercare di indirizzare l'elemento giusto e applicarlo -webkit-transform: translate3d(0,0,0)solo a esso.

Modifica: a volte translate3D(0,0,0)non funziona, possiamo usare il seguente metodo, prendendo di mira l'elemento giusto:

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

// ios redraw fix
animation: redraw 1s linear infinite;

Stavo affrontando lo stesso problema. È possibile utilizzare il body *selettore anziché *:not(html). Risolverà il tuo problema.
kunal

Complimenti per il suggerimento di colpire gli elementi giusti piuttosto che inquinare tutto con il *
Maciek Rek

7

Quando translate3d non funziona, prova ad aggiungere prospettiva. Funziona sempre per me

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


santa c $ # @ finalmente una soluzione angolare / ionica. -webkit-perspective: 1000;
lilbiscuit

Ahh mi ha salvato la giornata. +1 per te;)
Omar Bahir,

Ciò ha causato il crash del mio browser iOS.
Andreas Richter,

-webkit-perspective: 1000;l'ho fatto per me - grazie
jHilscher il

2

L'aggiunta -webkit-transform: translate3d(0,0,0)statica a un elemento non funziona per me.

Applico questa proprietà in modo dinamico. Ad esempio, quando si scorre una pagina, ho impostato -webkit-transform: translate3d(0,0,0)un elemento. Quindi dopo un breve ritardo, ho resettato questa proprietà, ovvero, -webkit-transform: none questo approccio sembra funzionare.

Grazie, @Colin Williams per avermi indicato nella giusta direzione.


Questo suggerimento mi ha aiutato molto, dal momento che questi stili hanno alcuni effetti collaterali indesiderati, di solito voglio evitare. Quindi uso gli eventi touchstart / touchend per aggiungerli e rimuoverli. Grazie!
Windwalker,

1

Ho avuto lo stesso problema con iscroll 4.2.5 su iOS7. L'intero elemento di scorrimento scompare. Ho provato ad aggiungere translate3d(0,0,0)come suggerito qui, ha risolto il problema, ma ha disabilitato l'effetto "snap" di iscroll. La soluzione è arrivata fornendo "position:relative; z-index:1000;display:block"proprietà CSS all'intero contenitore che contiene l'elemento scroll e non è necessario assegnare translate3d agli elementi figlio.


Ho usato questa tecnica per risolvere un problema simile su Android Chrome. Lo scorrimento verticale sembrava funzionare meglio di quando ho provato la correzione translate3d. Nel mio caso l' <body>elemento è quello che ho usato per lo scorrimento e una versione semplificata ha funzionato:body { position: relative; z-index: 0; }
BumbleB2na,

1

Al momento translate3dpotrebbe non funzionare, in quei casi perspectivepuò essere utilizzato

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

0

Sono abbastanza sicuro di averlo appena risolto con:

overflow-y: auto;

(Presumibilmente overflow: auto;funzionerebbe anche troppo a seconda delle tue esigenze.)


Non ha fatto nulla per me, mentre la risposta accettata ha probabilmente fatto uno scenario diverso
Tony

0

Ci sono casi in cui viene applicata una rotazione e / o viene utilizzato un indice Z.

Rotazione : una dichiarazione esistente di -webkit-transformrotazione di un elemento potrebbe non essere sufficiente per affrontare anche il problema dell'aspetto (come -webkit-transform: rotate(-45deg)). In questo caso puoi usare -webkit-transform: translateZ(0px) rotateZ(-45deg)come trucco ( attenzione alla rotazione della Z ).

Indice Z : insieme alla rotazione potresti definire una z-indexproprietà positiva , come z-index: 42. I passaggi precedenti descritti in "Rotazione" erano nel mio caso sufficienti per risolvere il problema, anche con il vuoto translateZ(0px). Sospetto però che l'indice Z in questo caso possa aver causato la scomparsa e la ricomparsa in primo luogo. In ogni caso la z-index: 42proprietà deve essere mantenuta - -webkit-transform: translateZ(42px)solo non è sufficiente.


0

Questo è un problema molto comune affrontato dagli sviluppatori ed è principalmente dovuto alla Safari'sproprietà di non ricreare gli elementi definiti come position : fixed.

Quindi o modificare la proprietà position o alcuni hack devono essere applicati come indicato in altre risposte.

link1

Link2


0

Nel mio caso (un'app Phonegap per iOS), l'applicazione di translate3d ai relativi elementi figlio non ha risolto il problema. Il mio elemento scorrevole non aveva un'altezza impostata in quanto era assolutamente posizionato e stavo definendo le posizioni superiore e inferiore. Ciò che l'ha risolto per me è stato l'aggiunta di un'altezza minima (di 100px).


0

Ho avuto lo stesso problema con una versione precedente di Fancybox. L'aggiornamento alla v3 risolverà il tuo problema O puoi semplicemente aggiungere:

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

0

Ho affrontato questo problema in un progetto Framework7 e Cordova. Ho provato tutte le soluzioni sopra. Non hanno risolto il mio problema.

Nel mio caso, stavo usando 10+ animazioni CSS sulla stessa pagina con rotazione infinita (trasformazione). Ho dovuto rimuovere le animazioni. Ora va bene con la mancanza di alcune funzionalità visive.

Se le soluzioni di cui sopra non ti aiutano, potresti iniziare ad eliminare alcune animazioni.


0

il -webkit-transform: translate3d(0, 0, 0);trucco non ha funzionato per me. Nel mio caso avevo impostato un genitore su:

// parent
height: 100vh;

Modificandolo in:

height: auto;
min-height: 100vh;

Risolto il problema nel caso in cui qualcun altro stesse affrontando la stessa situazione.


0

Nel mio caso, CSS non ha risolto il problema. Ho notato il problema durante l'utilizzo di jQuery ri-rendering di un pulsante.

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

Prova questo

$("#myButton").html("<span>text</span>")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.