Pengguliran iPad Safari menyebabkan elemen HTML menghilang dan muncul kembali dengan penundaan

165

Saat ini saya sedang mengembangkan aplikasi web menggunakan html5 dan jQuery untuk iPad Safari. Saya mengalami masalah di mana area gulir besar menyebabkan elemen-elemen yang offscreen muncul setelah penundaan ketika saya gulir ke bawah ke mereka.

Yang saya maksud dengan itu adalah, jika saya memiliki deretan gambar (atau bahkan div dengan gradien) yang offscreen, ketika saya gulir ke bawah (atau ke atas) ke sana, perilaku yang diharapkan adalah agar elemen muncul di layar sebagai Saya menggulir ke sana.

Namun, yang saya lihat adalah bahwa elemen tidak muncul sampai saya mengangkat jari saya dari layar dan scroller menyelesaikan semua animasinya.

Ini menyebabkan masalah yang sangat mencolok bagi saya, membuat semuanya terlihat berombak, meskipun tidak. Saya menduga iPad Safari sedang mencoba melakukan sesuatu untuk menghemat memori. Apakah ada cara di mana saya dapat mencegah ini berombak terjadi. Selain itu, saya juga akan menghargai jika ada yang bisa menjelaskan apa yang sebenarnya dilakukan oleh Safari iPad.

codeBearer
sumber
Masalah / solusi ini membantu saya memperbaiki masalah dengan versi jPanelMenu 1.3 CSS Transforms, yang mengubah semua yang ada di situs saya invisibie hingga saya menambahkan cuplikan di atas.
Trombone ke
2
Menggunakan *: tidak (html) akan menerapkan translate3d ke semua aspek lain dari situs Anda dan saya tidak merekomendasikan. Ini akan menyebabkan gambar di tab menghilang saat Anda menggulir ke bawah, dll, bug yang mungkin Anda gunakan hanya untuk melihat gambar 3D Anda sekarang akan hadir di aspek lain dari situs Anda.
Jonathan Tonge
1
Saya memiliki beberapa <svg>elemen yang menunjukkan gambar / render tertunda serupa. Sayangnya, *:not(html) { ... }menyebabkan segala macam perilaku aneh, seperti yang ditunjukkan oleh @JonathanTonge. Namun, hanya memilih <svg>elemen dan menggunakan translate3d(0, 0, 0,);tampaknya telah menyelesaikan masalah gulir saya.
Zephyr Mays
Kecuali untuk kasus penggunaan yang sangat spesifik, ini adalah sampah. Benar-benar mengacaukan tata letak yang bergantung pada elemen posisi absolut.
Stoutie
2
Silakan posting jawaban sebagai jawaban, bukan "EDIT" dalam pertanyaan Anda. Saya tahu Anda paling menyukai jawaban Anda, dan itu tidak masalah, tetapi StackOverflow memiliki format T&J yang berfungsi paling baik bila T berbeda dari A.
Slipp D. Thompson

Jawaban:

184

Anda perlu menipu browser untuk menggunakan akselerasi perangkat keras dengan lebih efektif. Anda dapat melakukan ini dengan transformasi 3d kosong:

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

Khususnya, Anda akan membutuhkan ini pada elemen anak yang memiliki position:relative;deklarasi (atau, lakukan saja dan lakukan untuk semua elemen anak).

Bukan perbaikan yang dijamin, tetapi cukup berhasil sebagian besar waktu.

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

Colin Williams
sumber
3
Saya mencobanya juga. Sayangnya, menambahkan translate3d memotong elemen-elemen yang ditampilkan dengan benar sebelumnya. Saya juga membutuhkan akselerasi perangkat keras untuk beberapa objek yang offscreen dan harus dianimasikan untuk "terbang" di layar. Saya menggunakan jQuery's animate (), yang sangat lambat. Saya beralih menggunakan akselerasi perangkat keras. Meskipun itu mempercepat animasi, itu menghasilkan hasil yang tidak menentu, dalam arti bahwa beberapa elemen anak dari orangtua (animating) div dipotong. Ini tidak terjadi ketika saya menggunakan animate ().
codeBearer
1
@Colin Williams Anda baru saja membuat hari saya! : D
Luke
9
Wow, itu mengerikan tetapi efektif. Terima kasih.
Tim Down
1
Pria bintang emas freakin! Saya menambahkannya ke semua elemen li saya di div yang dapat digulir. Puf. Bekerja.
Bryan Johnson
68

Ini adalah jawaban lengkap untuk pertanyaan saya. Saya awalnya menandai jawaban @Colin Williams sebagai jawaban yang benar, karena membantu saya mendapatkan solusi lengkap. Seorang anggota komunitas, @ Slipp D. Thompson, mengedit pertanyaan saya, setelah sekitar 2,5 tahun saya menanyakannya, dan mengatakan bahwa saya menyalahgunakan format Tanya Jawab SO. Dia juga mengatakan kepada saya untuk secara terpisah memposting ini sebagai jawabannya. Jadi, inilah jawaban lengkap yang memecahkan masalah saya:

@Colin Williams, terima kasih! Jawaban Anda dan artikel yang Anda tautkan memberi saya petunjuk untuk mencoba sesuatu dengan CSS.

Jadi, saya menggunakan translate3d sebelumnya. Ini menghasilkan hasil yang tidak diinginkan. Pada dasarnya, itu akan memotong dan BUKAN elemen RENDER yang offscreen, sampai saya berinteraksi dengan mereka. Jadi, pada dasarnya, dalam orientasi lansekap, setengah dari situs saya yang offscreen tidak ditampilkan. Ini adalah aplikasi web iPad, karena saya sedang dalam perbaikan.

Menerapkan translate3d ke elemen-elemen yang relatif diposisikan memecahkan masalah untuk elemen-elemen itu, tetapi elemen-elemen lain berhenti di-render, setelah offscreen. Elemen yang saya tidak bisa berinteraksi dengan (karya seni) tidak akan pernah merender lagi, kecuali saya memuat ulang halaman.

Solusi lengkap:

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

Sekarang, meskipun ini mungkin bukan solusi yang paling "efisien", itu adalah satu-satunya yang berfungsi. Mobile Safari tidak membuat elemen-elemen yang offscreen, atau terkadang membuat tidak menentu, saat menggunakan -webkit-overflow-scrolling: touch. Kecuali jika translate3d diterapkan ke semua elemen lain yang mungkin menjadi layar karena gulir itu, elemen-elemen itu akan dipotong setelah menggulir.

Jadi, terima kasih lagi, dan harap ini membantu jiwa yang hilang lainnya. Ini pasti sangat membantu saya!

codeBearer
sumber
2
Wow. Terima kasih untuk ini. Ini menyelamatkan saya dari sakit kepala yang sangat besar untuk aplikasi phonegap / cordova saya. Dalam kasus saya, saya harus berubah *:not(html)kebody *
anon
9
hanya menerapkan -webkit-transform: translate3d(0, 0, 0);pada elemen masalah yang bekerja untuk saya. Dalam kasus saya, saya menggunakan ScrollMagic
fidev
Tak satu pun dari ini bekerja untuk saya juga. Segera setelah saya gulir ke bawah ke titik tertentu, hal-hal yang tidak lagi terlihat di atas jendela menjadi hijau, serta beberapa elemen di viewport. Saya melihat "sentakan" yang sangat ringan tapi tidak salah ketika bergulir setelah elemen-elemen disemprot. (Yaitu: halus - gelisah - perilaku halus, seperti tersendat saat menggulir.) Ini ada di iPad.
cbmtrx
BTW Saya baru menemukan bahwa di iPad Air 2, ketika elemen di layar tertentu (navbar, dalam kasus ini) mati layar, perangkat "memuat ulang" yang memblokir - hanya menggunakan versi besar, bukan yang sedang asli bahwa halaman dimuat. Apa yang ...
cbmtrx
Jika ada yang mengalami keanehan yang sama dengan saya - sedikit berbeda dari yang dijelaskan pada halaman ini - saya menemukan bahwa menggunakan $(window).width()alih-alih window.innerWidthdi jQuery membuat semua perbedaan untuk iOS. Siapa tahu.
cbmtrx
13

Menargetkan semua elemen kecuali html: *:not(html) menyebabkan masalah pada elemen lain dalam kasus saya. Itu memodifikasi konteks penumpukan, menyebabkan beberapa indeks-z rusak.

Kita sebaiknya mencoba menargetkan elemen yang tepat dan menerapkannya -webkit-transform: translate3d(0,0,0)saja.

Sunting: terkadang translate3D(0,0,0)tidak berhasil, kita dapat menggunakan metode berikut, menargetkan elemen yang tepat:

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

// ios redraw fix
animation: redraw 1s linear infinite;
Guillaume Gautier
sumber
Saya menghadapi masalah yang sama. Anda bisa menggunakan body *pemilih daripada *:not(html). Ini akan menyelesaikan masalah Anda.
kunal
Kudos atas saran untuk menargetkan elemen yang tepat daripada mencemari segala sesuatu dengan *
Maciek Rek
7

Ketika translate3d tidak berfungsi, coba tambahkan perspektif. Itu selalu berhasil untuk saya

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
sumber
holy c $ # @ akhirnya solusi untuk angular / ionic. -webkit-perspective: 1000;
lilbiscuit
Ahh Menyelamatkan hariku. +1 untuk Anda;)
Omar Bahir
Ini membuat browser iOS saya mogok.
Andreas Richter
-webkit-perspective: 1000;melakukannya untuk saya - terima kasih
jHilscher
2

Menambahkan -webkit-transform: translate3d(0,0,0)ke elemen secara statis tidak berfungsi untuk saya.

Saya menerapkan properti ini secara dinamis. Misalnya, ketika halaman digulir, saya mengatur -webkit-transform: translate3d(0,0,0)elemen. Kemudian setelah penundaan singkat, saya mereset properti ini, yaitu, -webkit-transform: none Pendekatan ini sepertinya berhasil.

Terima kasih, @Colin Williams karena mengarahkan saya ke arah yang benar.

Alexander Poleschuk
sumber
Petunjuk ini sangat membantu saya, karena gaya-gaya ini mengandung beberapa efek samping yang tidak diinginkan, saya biasanya ingin menghindarinya. Jadi saya menggunakan touchstart / touchend events untuk menambah dan menghapusnya. Terima kasih!
Windwalker
1

Saya memiliki masalah yang sama dengan iscroll 4.2.5 di ios7. Seluruh elemen gulir menghilang begitu saja. Saya sudah mencoba menambahkan translate3d(0,0,0)seperti yang disarankan di sini, ia telah memecahkan masalah, tetapi menonaktifkan efek "jepret" iscroll. Solusinya datang dengan memberikan "position:relative; z-index:1000;display:block"properti css ke seluruh wadah yang menampung elemen gulir dan tidak perlu memberikan translate3d ke elemen anak.

yudarik
sumber
Saya menggunakan teknik ini untuk memecahkan masalah serupa di Android Chrome. Pengguliran vertikal tampaknya berkinerja lebih baik daripada ketika saya mencoba memperbaiki translate3d. Dalam <body>elemen kasus saya adalah apa yang saya gunakan untuk menggulir dan versi yang disederhanakan bekerja:body { position: relative; z-index: 0; }
BumbleB2na
1

Pada saat translate3dmungkin tidak berfungsi, dalam kasus-kasus tersebut perspectivedapat digunakan

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

Saya sangat yakin saya baru saja menyelesaikan ini dengan:

overflow-y: auto;

(Agaknya hanya overflow: auto;akan bekerja tergantung pada kebutuhan Anda.)

David Notik
sumber
Saya tidak melakukan apa-apa bagi saya sedangkan jawaban yang diterima mungkin skenario yang berbeda
tony
0

Ada kasus di mana rotasi diterapkan dan / atau indeks Z digunakan.

Rotasi : Deklarasi yang ada -webkit-transformuntuk memutar elemen mungkin tidak cukup untuk mengatasi masalah penampilan (seperti -webkit-transform: rotate(-45deg)). Dalam hal ini Anda dapat menggunakan -webkit-transform: translateZ(0px) rotateZ(-45deg)sebagai trik ( mind the rotate Z ).

Indeks Z : Bersama dengan rotasi, Anda dapat menentukan z-indexproperti positif , seperti z-index: 42. Langkah-langkah di atas yang dijelaskan di bawah "Rotasi" ada dalam kasus saya cukup untuk menyelesaikan masalah, bahkan dengan yang kosong translateZ(0px). Namun saya menduga bahwa indeks Z dalam kasus ini mungkin telah menyebabkan menghilang dan muncul kembali di tempat pertama. Dalam kasus apa pun z-index: 42properti perlu dijaga - -webkit-transform: translateZ(42px)hanya saja tidak cukup.

Stefan Zurfluh
sumber
0

Ini adalah masalah yang sangat umum yang dihadapi oleh pengembang dan itu terutama disebabkan oleh Safari'ssifat elemen yang tidak diciptakan ulang position : fixed.

Jadi baik mengubah properti posisi atau beberapa peretasan perlu diterapkan seperti yang disebutkan dalam jawaban lain.

Tautan1

Link2

arqam
sumber
0

Dalam kasus saya (aplikasi iOS Phonegap), menerapkan translate3d ke elemen anak relatif tidak menyelesaikan masalah. Elemen yang dapat digulir tidak memiliki ketinggian yang diatur karena benar-benar diposisikan dan saya mendefinisikan posisi atas dan bawah. Apa yang diperbaiki untuk saya adalah menambahkan min-height (100px).

b4tch
sumber
0

Saya memiliki masalah yang sama menggunakan Fancybox versi lama. Memutakhirkan ke v3 akan menyelesaikan masalah Anda ATAU Anda bisa menambahkan:

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

Saya menghadapi masalah ini dalam proyek Framework7 & Cordova. Saya mencoba semua solusi di atas. Mereka tidak menyelesaikan masalah saya.

Dalam kasus saya, saya menggunakan animasi 10+ css pada halaman yang sama dengan rotasi tak terbatas (transform). Saya harus menghapus animasi. Tidak apa-apa sekarang dengan kurangnya beberapa fitur visual.

Jika solusi di atas tidak membantu Anda, Anda dapat mulai menghilangkan beberapa animasi.

yavuzkirez
sumber
0

yang -webkit-transform: translate3d(0, 0, 0);trik tidak bekerja untuk saya. Dalam kasus saya, saya telah menetapkan orangtua ke:

// parent
height: 100vh;

Mengubah itu menjadi:

height: auto;
min-height: 100vh;

Memecahkan masalah jika ada orang lain yang menghadapi situasi yang sama.

funador
sumber
0

Dalam kasus saya, CSS tidak memperbaiki masalah. Saya perhatikan masalah saat menggunakan jQuery membuat ulang tombol.

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

Coba ini

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