Dalam aplikasi Angular 2 saya ketika saya menggulir ke bawah halaman dan mengklik tautan di bagian bawah halaman, itu memang mengubah rute dan membawa saya ke halaman berikutnya tetapi itu tidak gulir ke bagian atas halaman. Akibatnya, jika halaman pertama panjang dan halaman ke-2 memiliki sedikit konten, itu memberi kesan bahwa halaman ke-2 tidak memiliki konten. Karena konten hanya dapat dilihat jika pengguna menggulir ke bagian atas halaman.
Saya dapat menggulirkan jendela ke bagian atas halaman dengan ngInit dari komponen tetapi, apakah ada solusi yang lebih baik yang secara otomatis dapat menangani semua rute di aplikasi saya?
RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
Jawaban:
Anda dapat mendaftarkan pendengar perubahan rute pada komponen utama Anda dan gulir ke atas pada perubahan rute.
sumber
window.scrollTo(0, 0)
adalahdocument.body.scrollTop = 0;
IMO yang lebih ringkas daripada , dan lebih mudah dibaca.$("body").animate({ scrollTop: 0 }, 1000);
daripadawindow.scrollTo(0, 0)
menghidupkanSudut 6.1 dan yang lebih baru :
Angular 6.1 (dirilis pada 2018-07-25) menambahkan dukungan bawaan untuk menangani masalah ini, melalui fitur yang disebut "Router Scroll Position Restoration". Seperti yang dijelaskan di blog resmi Angular , Anda hanya perlu mengaktifkan ini di konfigurasi router seperti ini:
Selanjutnya, blog menyatakan "Diharapkan bahwa ini akan menjadi default dalam rilis utama di masa depan". Sejauh ini ini belum terjadi (pada Angular 8.2), tetapi pada akhirnya Anda tidak perlu melakukan apa pun dalam kode Anda, dan ini hanya akan berfungsi dengan baik di luar kotak.
Anda dapat melihat detail lebih lanjut tentang fitur ini dan cara menyesuaikan perilaku ini di dokumen resmi .
6.0 sudut dan sebelumnya :
Sementara jawaban GuilhermeMeireles yang luar biasa memperbaiki masalah aslinya, ia memperkenalkan yang baru, dengan memutus perilaku normal yang Anda harapkan ketika Anda menavigasi kembali atau meneruskan (dengan tombol browser atau melalui Lokasi dalam kode). Perilaku yang diharapkan adalah ketika Anda menavigasi kembali ke halaman, itu harus tetap digulir ke bawah ke lokasi yang sama ketika Anda mengklik tautan, tetapi menggulir ke atas ketika tiba di setiap halaman jelas-jelas mematahkan harapan ini.
Kode di bawah ini memperluas logika untuk mendeteksi navigasi semacam ini dengan berlangganan urutan PopStateEvent Lokasi dan melewatkan logika scroll-to-top jika halaman yang baru tiba adalah hasil dari peristiwa semacam itu.
Jika halaman yang Anda navigasikan kembali cukup panjang untuk menutupi seluruh viewport, posisi gulir dipulihkan secara otomatis, tetapi seperti yang ditunjukkan oleh @JordanNelson, jika halaman lebih pendek, Anda perlu melacak posisi gulir y asli dan mengembalikannya secara eksplisit ketika Anda kembali ke halaman. Versi kode yang diperbarui mencakup kasus ini juga, dengan selalu secara eksplisit mengembalikan posisi gulir.
sumber
body
?Dari Angular 6.1, Anda sekarang dapat menghindari kerumitan dan beralih
extraOptions
keRouterModule.forRoot()
parameter Anda sebagai parameter kedua dan dapat menentukanscrollPositionRestoration: enabled
untuk memberitahu Angular untuk menggulir ke atas setiap kali rute berubah.Secara default Anda akan menemukan ini di
app-routing.module.ts
:Dokumen Resmi Sudut
sumber
Anda dapat menulis ini dengan lebih ringkas dengan memanfaatkan
filter
metode yang bisa diamati :Jika Anda mengalami masalah untuk menggulir ke atas saat menggunakan sidenav Bahan Sudut 2 ini akan membantu. Jendela atau badan dokumen tidak akan memiliki bilah gulir sehingga Anda perlu mendapatkan
sidenav
wadah konten dan gulir elemen itu, jika tidak coba gulir jendela sebagai default.Juga, Angular CDK v6.x sekarang memiliki paket gulir yang mungkin membantu menangani pengguliran.
sumber
document.querySelector('.mat-sidenav-content .content-div').scrollTop = 0;
Jika Anda memiliki rendering sisi server, Anda harus berhati-hati untuk tidak menjalankan kode yang digunakan
windows
pada server, di mana variabel itu tidak ada. Ini akan menghasilkan pemecahan kode.isPlatformBrowser
adalah fungsi yang digunakan untuk memeriksa apakah platform saat ini di mana aplikasi diberikan adalah browser atau tidak. Kami berikan yang disuntikkanplatformId
.Itu juga mungkin untuk memeriksa keberadaan variabel
windows
, agar aman, seperti ini:sumber
PLATFORM_ID
dalamconstructor
dan memberikan nilai ini sebagai parameter dalam deisPlatformBrowser
metode?isPlatformBrowser
adalah fungsi dan akan selalu jujur. Saya sudah mengeditnya sekarang.lakukan saja dengan mudah dengan aksi klik
di html komponen utama Anda buat referensi #scrollContainer
di komponen utama .ts
sumber
scrollContainer
node pertama, Anda mungkin perlu menggali sedikit di objek, bagi saya apa yang benar-benar berfungsi adalahscrollContainer .scrollable._elementRef.nativeElement.scrollTop = 0
Angular baru-baru ini memperkenalkan fitur baru, di dalam modul routing sudut melakukan perubahan seperti di bawah ini
sumber
Jawaban terbaik ada di diskusi Angular GitHub ( Mengubah rute tidak gulir ke atas di halaman baru ).
app.component.html
app.component.ts
Kredit penuh untuk JoniJnm ( pos asli )
sumber
Anda dapat menambahkan kait siklus hidup AfterViewInit ke komponen Anda.
sumber
Pada Angular 6.1, router menyediakan opsi konfigurasi yang disebut
scrollPositionRestoration
, ini dirancang untuk memenuhi skenario ini.sumber
Jika Anda hanya perlu menggulir halaman ke atas, Anda dapat melakukan ini (bukan solusi terbaik, tetapi cepat)
sumber
Inilah solusi yang saya buat. Saya memasangkan LocationStrategy dengan peristiwa Router. Menggunakan LocationStrategy untuk menetapkan boolean untuk mengetahui kapan pengguna saat ini menelusuri riwayat peramban. Dengan cara ini, saya tidak perlu menyimpan banyak URL dan data gulir y (yang tidak berfungsi dengan baik, karena setiap data diganti berdasarkan URL). Ini juga menyelesaikan tepi kasus ketika pengguna memutuskan untuk menahan tombol maju atau mundur pada browser dan kembali atau maju beberapa halaman daripada hanya satu.
PS Saya hanya menguji pada versi terbaru dari IE, Chrome, FireFox, Safari, dan Opera (pada posting ini).
Semoga ini membantu.
sumber
Solusi ini didasarkan pada solusi @ FernandoEcheverria dan @ GuilhermeMeireles, tetapi lebih ringkas dan berfungsi dengan mekanisme popstate yang disediakan oleh Angular Router. Ini memungkinkan untuk menyimpan dan mengembalikan level gulir dari beberapa navigasi berurutan.
Kami menyimpan posisi gulir untuk setiap kondisi navigasi di peta
scrollLevels
. Setelah ada acara popstate, ID dari negara yang akan dikembalikan dipasok oleh sudut Router:event.restoredState.navigationId
. Ini kemudian digunakan untuk mendapatkan tingkat gulir terakhir dari kondisi ituscrollLevels
.Jika tidak ada level gulir yang tersimpan untuk rute, itu akan bergulir ke atas seperti yang Anda harapkan.
sumber
scrollTop
vsscrollY
.Selain jawaban sempurna yang diberikan oleh @Guilherme Meireles seperti yang ditunjukkan di bawah ini, Anda dapat mengubah penerapan Anda dengan menambahkan gulir halus seperti yang ditunjukkan di bawah ini
lalu tambahkan cuplikan di bawah ini
ke styles.css Anda
sumber
untuk iphone / ios safari Anda dapat membungkusnya dengan setTimeout
sumber
height: 100vh + 1px;
Hai guys ini bekerja untuk saya di sudut 4. Anda hanya perlu referensi orang tua untuk gulir pada perubahan router`
layout.component.pug
layout.component.ts
sumber
@Fernando Echeverria hebat! tetapi kode ini tidak berfungsi di router hash atau router malas. karena mereka tidak memicu perubahan lokasi. dapat mencoba ini:
sumber
Menggunakannya
Router
sendiri akan menyebabkan masalah yang tidak dapat Anda atasi sepenuhnya untuk mempertahankan pengalaman browser yang konsisten. Menurut pendapat saya metode terbaik adalah dengan hanya menggunakan kebiasaandirective
dan biarkan ini mereset gulir saat klik. Hal yang baik tentang ini, adalah bahwa jika Anda berada di samaurl
dengan yang Anda klik, halaman akan menggulir kembali ke atas juga. Ini konsisten dengan situs web normal. Dasardirective
bisa terlihat seperti ini:Dengan penggunaan berikut:
Ini akan cukup untuk sebagian besar kasus penggunaan, tapi saya bisa membayangkan beberapa masalah yang mungkin timbul dari ini:
universal
karena penggunaanwindow
Sebenarnya cukup mudah untuk mengatasi masalah ini:
Ini memperhitungkan sebagian besar kasus penggunaan, dengan penggunaan yang sama seperti kasus dasar, dengan keuntungan mengaktifkan / menonaktifkannya:
iklan, jangan baca jika Anda tidak ingin diiklankan
Perbaikan lain dapat dilakukan untuk memeriksa apakah browser mendukung
passive
acara atau tidak . Ini akan memperumit kode sedikit lebih, dan agak tidak jelas jika Anda ingin menerapkan semua ini dalam arahan / templat kustom Anda. Itu sebabnya saya menulis perpustakaan kecil yang dapat Anda gunakan untuk mengatasi masalah ini. Untuk memiliki fungsi yang sama seperti di atas, dan denganpassive
acara yang ditambahkan , Anda dapat mengubah arahan Anda untuk ini, jika Anda menggunakanng-event-options
perpustakaan. Logikanya ada di dalamclick.pnb
pendengar:sumber
Ini bekerja untuk saya yang terbaik untuk semua perubahan navigasi termasuk navigasi hash
sumber
Gagasan utama di balik kode ini adalah untuk menjaga semua url yang dikunjungi bersama dengan data gulir masing-masing dalam array. Setiap kali pengguna meninggalkan halaman (NavigationStart) array ini diperbarui. Setiap kali pengguna memasuki halaman baru (NavigationEnd), kami memutuskan untuk mengembalikan posisi Y atau tidak tergantung pada bagaimana kita sampai ke halaman ini. Jika referensi pada beberapa halaman digunakan kita gulir ke 0. Jika fitur back / forward browser digunakan kita gulir ke Y disimpan dalam array kita. Maaf untuk bahasa Inggris saya :)
sumber
window.scrollTo()
tidak bekerja untuk saya dalam Angular 5, jadi saya telah menggunakandocument.body.scrollTop
seperti,sumber
Jika Anda memuat komponen yang berbeda dengan rute yang sama maka Anda dapat menggunakan ViewportScroller untuk mencapai hal yang sama.
sumber
window scroll top
Kedua window.pageYOffset dan document.documentElement.scrollTop mengembalikan hasil yang sama di semua case. window.pageYOffset tidak didukung di bawah IE 9.
app.component.ts
app.component.html
sumber