Topik temu duga representatif

Temu duga Frontend: Bagaimanakah anda membina animasi pacuan skrol (scroll-driven animation) dengan selamat?

FrontendSederhana
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Halaman produk memerlukan penunjuk kemajuan dan kad yang beranimasi semasa memasuki port pandangan (viewport). Reka bentuk pelaksanaan pacuan skrol, jelaskan garis masa kemajuan skrol berbanding paparan, sokong pelayar lama, dan kekalkan prestasi serta kebolehcapaian.

Gesaan dan kes penggunaan

Matlamatnya adalah untuk mengikat kemajuan animasi dengan penatalan tanpa menjalankan pengendali JavaScript pada setiap peristiwa skrol. Animasi pacuan skrol CSS mendedahkan garis masa scroll-progress dan view-progress melalui animation-timeline, scroll(), dan view(). Pelaksanaan ini masih memerlukan sandaran (fallback), tingkah laku pergerakan dikurangkan, keputusan pembendungan (containment), dan dasar sokongan pelayar yang jelas.

Perkara yang dinilai oleh penemu duga

  • Sama ada anda membezakan kemajuan bekas skrol daripada kemajuan keterlihatan sesuatu elemen.
  • Sama ada anda meletakkan deklarasi animation-timeline selepas trengkas (shorthand) animation.
  • Sama ada anda memilih transform dan opacity sebelum sifat yang mencetuskan susun atur.
  • Sama ada anda menyediakan pertanyaan ciri (feature query) atau garis dasar tanpa animasi.
  • Sama ada anda menghormati prefers-reduced-motion dan mengekalkan kandungan yang boleh dibaca tanpa pergerakan.
  • Sama ada anda mengukur halaman panjang, penskrol bersarang, elemen melekit (sticky), dan prestasi mudah alih.

Penjelasan sebelum menjawab

  • Adakah kemajuan terikat pada halaman, bekas skrol bersarang, atau elemen yang memasuki port pandangan?
  • Adakah animasi mesti menyampaikan status, atau sekadar hiasan?
  • Pelayar dan paparan web terbenam (embedded webviews) manakah yang berada dalam skop?
  • Apakah yang patut dilihat oleh pengguna dengan pergerakan dikurangkan?
  • Bolehkah reka bentuk diturunkan taraf kepada bar kemajuan statik atau pendedahan statik?
  • Adakah terdapat leluhur melekit, terjelma (transformed), atau divirtualkan yang mengubah blok pembendung?

Rangka kerja jawapan 30 saat

“Saya akan menggunakan garis masa scroll-progress untuk kemajuan halaman dan garis masa view-progress untuk kad yang memasuki penskrol. Saya akan mentakrifkan garis dasar statik yang boleh dibaca, kemudian meningkatkan di dalam pertanyaan ciri dengan animation-timeline diisytiharkan selepas trengkas animasi. Saya akan menganimasikan transform atau opacity, menguji penskrol bersarang dan elemen melekit, serta melumpuhkan pergerakan yang tidak penting di bawah prefers-reduced-motion. Saya akan mengesahkan sokongan, kos bingkai, akses papan kekunci, dan pemahaman kandungan sebelum membuat penghantaran.”

Jawapan mendalam langkah demi langkah

Langkah 1: Pilih garis masa.

Gunakan garis masa scroll-progress apabila animasi dipetakan kepada julat skrol bagi sesuatu bekas. Gunakan garis masa view-progress apabila animasi dipetakan kepada perjalanan elemen melalui scrollport.

Langkah 2: Bina garis dasar.

Paparkan penunjuk kemajuan dan kad dalam keadaan statik yang berguna terlebih dahulu. Pelayar yang mengabaikan animasi sepatutnya masih mendedahkan kandungan, susunan, kontras, dan kawalan.

Langkah 3: Tambah peningkatan CSS.

css
@supports (animation-timeline: scroll()) {
  .progress {
    animation: grow-progress linear both;
    animation-timeline: scroll(root block);
  }

  .card {
    animation: reveal linear both;
    animation-timeline: view(block);
    animation-range: entry 0% cover 35%;
  }
}

Isytiharkan animation-timeline selepas trengkas kerana trengkas menetapkan semula sub-sifat yang berkaitan dengan garis masa. Namakan garis masa secara eksplisit apabila bekas skrol bersarang boleh menyebabkan penskrol terdekat menjadi kabur.

Langkah 4: Pastikan sifat yang dianimasikan berkos rendah.

Utamakan opacity dan transform. Elakkan menganimasikan width, height, top, left, atau bayang-bayang besar pada senarai panjang melainkan pemprofilan membuktikan kos tersebut boleh diterima. Jangan tambah will-change pada setiap kad hanya sebagai tekaan.

Langkah 5: Kendalikan pergerakan dikurangkan.

css
@media (prefers-reduced-motion: reduce) {
  .progress,
  .card {
    animation: none;
    transform: none;
    opacity: 1;
  }
}

Kandungan dan maksud kemajuan mesti kekal tersedia tanpa animasi. Keadaan serta-merta yang halus atau penunjuk statik adalah lebih selamat daripada sekadar memendekkan peralihan yang panjang.

Langkah 6: Uji geometri dan sokongan.

Uji penskrol akar, penskrol bersarang mendatar dan menegak, elemen melekit, kandungan dinamik, zum, navigasi papan kekunci, dan perubahan port pandangan mudah alih. Pengesanan ciri harus mengawal peningkatan, bukan menyembunyikan garis dasar.

Langkah 7: Ukur dan perhatikan.

Gunakan surihan prestasi DevTools untuk memeriksa kerja gaya, susun atur, cat (paint), dan penggubah (compositor). Uji senarai panjang dan peranti mudah alih berkuasa rendah, dan perhatikan kandungan yang menjadi tidak boleh dibaca apabila garis masa tidak disokong atau terganggu.

Contoh jawapan berkualiti tinggi

“Bar kemajuan halaman menggunakan scroll(root block) kerana nilainya ialah julat skrol akar. Setiap kad menggunakan view(block) dengan julat kemasukan-ke-liputan (entry-to-cover) kerana pendedahannya harus mengikut keterlihatannya sendiri. Saya memaparkan kad secara normal terlebih dahulu, kemudian menambah garis masa di dalam @supports; perisytiharan tersebut mengikuti trengkas animasi. Saya mengehadkan pergerakan kepada transform dan opacity, mengalih keluar animasi tidak penting untuk pengguna pergerakan dikurangkan, dan menamakan penskrol apabila penataan sarang menyebabkan bekas terdekat menjadi kabur. Saya menguji akses papan kekunci, kandungan melekit dan dinamik, pelayar yang tidak disokong, dan senarai mudah alih yang panjang dengan surihan prestasi.”

Kesilapan lazim

  • Menggunakan peristiwa skrol untuk setiap bingkai → kerja pengendali boleh bersaing dengan penatalan → utamakan garis masa CSS apabila hubungan tersebut bersifat deklaratif.
  • Mengelirukan scroll() dan view() animasi bermula pada masa yang salah → petakan garis masa kepada kemajuan bekas atau keterlihatan elemen.
  • Meletakkan animation-timeline sebelum trengkas → trengkas boleh menetapkannya semula → isytiharkan garis masa selepasnya.
  • Menganimasikan sifat susun atur secara lalai → halaman panjang boleh mencetuskan kerja yang mahal → mulakan dengan transform dan opacity, kemudian lakukan pemprofilan.
  • Menghantar pergerakan tanpa pengendalian pergerakan dikurangkan → pengguna kehilangan kawalan terhadap keutamaan mereka → sediakan keadaan statik.
  • Menyembunyikan kandungan sehingga sokongan animasi wujud → pelayar yang tidak menyokong kehilangan maklumat → bina garis dasar terlebih dahulu.
  • Menganggap penskrol terdekat adalah betul → bekas bersarang mengubah garis masa → namakan atau uji penskrol yang dimaksudkan.

Soalan susulan dan jawapan

Susulan 1: Apakah perbezaan antara scroll() dan view()?

scroll() menjejaki kemajuan bekas skrol. view() menjejaki perkembangan keterlihatan elemen melalui scrollport bekas tersebut.

Susulan 2: Mengapakah garis masa mesti mengikuti trengkas?

Trengkas animation menetapkan semula sub-sifat yang berkaitan dengan garis masa, jadi perisytiharan garis masa sebelumnya boleh dikosongkan.

Susulan 3: Apakah sandarannya (fallback)?

Pastikan kandungan kelihatan dalam keadaan akhir yang boleh dibaca dan gunakan penunjuk kemajuan statik atau peningkatan JavaScript kecil hanya apabila keperluan produk benar-benar memerlukannya.

Susulan 4: Bagaimanakah anda menyokong pergerakan dikurangkan?

Lumpuhkan animasi tidak penting, alih keluar transform, dan kekalkan kandungan serta maksud status yang sama dengan gaya statik.

Susulan 5: Bolehkah anda menganimasikan height?

Hanya selepas pemprofilan dan dengan keperluan yang jelas. Transform dan opacity biasanya mengelakkan kerja susun atur; menganimasikan height boleh membatalkan susun atur merentas elemen adik-beradik.

Susulan 6: Apakah yang berlaku dalam penskrol bersarang?

Bekas skrol terdekat yang berkenaan mungkin berbeza daripada halaman. Uji geometri dan namakan garis masa yang dimaksudkan atau gunakan argumen penskrol yang betul.

Susulan 7: Bagaimanakah anda mengesahkannya dalam pengeluaran?

Rekod penggunaan sokongan pelayar, surihan prestasi pada peranti representatif, tingkah laku pergerakan dikurangkan, dan semakan kebolehcapaian. Kekalkan garis dasar statik supaya garis masa yang tidak disokong atau terganggu kekal boleh digunakan.

Sumber awam

Soalan berkaitan