Bagaimana cara mendapatkan posisi scrollbar dengan Javascript?

191

Saya mencoba mendeteksi posisi bilah gulir browser dengan JavaScript untuk memutuskan di mana di halaman tampilan saat ini. Dugaan saya adalah bahwa saya harus mendeteksi di mana ibu jari di trek, dan kemudian ketinggian ibu jari sebagai persentase dari total tinggi trek. Apakah saya terlalu memperumitnya, atau apakah JavaScript menawarkan solusi yang lebih mudah dari itu? Adakah ide yang bijak-kode?

Paul
sumber

Jawaban:

210

Anda dapat menggunakan element.scrollTopdan element.scrollLeftuntuk mendapatkan offset vertikal dan horizontal, masing-masing, yang telah digulir. elementbisa jadi document.bodyjika Anda peduli dengan seluruh halaman. Anda dapat membandingkannya dengan element.offsetHeightdan element.offsetWidth(sekali lagi, elementmungkin tubuh) jika Anda membutuhkan persentase.

Max Shawabkeh
sumber
2
Browser apa yang Anda gunakan? Mendapatkan tubuh dilakukan secara berbeda di berbagai browser ( elementdan document.bodyhanya contoh). Lihat howtocreate.co.uk/tutorials/javascript/browserwindow untuk detailnya.
Max Shawabkeh
8
Saya mendapatkannya untuk memberi saya nilai yang benar pada Firefox 3.6 dengan window.pageYOffset, tetapi tidak bisa mendapatkan apa pun yang bekerja di IE7. Mencoba window.pageYOffset, document.body.scrollTop, document.documentElement.scrollTop,element.scrollTop
Paul
1
scrollTop hanya bekerja untuk saya ketika saya menambahkan tanda kurung ... $ (". scrollBody"). scrollTop ()
maia
9
Jika Anda berurusan dengan Elemen 'window', Anda dapat menggunakan window.scrollY alih-alih window.scrollTop
Janis Jansen
6
Saya pikir posisi gulir tidak diaktifkan document.bodydi sebagian besar browser modern - biasanya diatur document.documentElementsekarang. Lihat bugs.chromium.org/p/chromium/issues/detail?id=157855 untuk transisi Chrome.
fzzfzzfzz
134

Saya melakukan ini untuk <div>di Chrome.

elemen .scrollTop - adalah piksel yang disembunyikan di atas karena gulir. Tanpa gulir nilainya adalah 0.

elemen .scrollHeight - adalah piksel seluruh div.

elemen .clientHeight - adalah piksel yang Anda lihat di browser Anda.

var a = element.scrollTop;

akan menjadi posisi.

var b = element.scrollHeight - element.clientHeight;

akan menjadi nilai maksimum untuk scrollTop .

var c = a / b;

akan menjadi persentase gulir [dari 0 ke 1] .

Gatsby
sumber
3
Ini hampir benar. untuk var b Anda harus mengurangi window.innerHeight bukan element.clientHeight.
Kahless
51
document.getScroll = function() {
    if (window.pageYOffset != undefined) {
        return [pageXOffset, pageYOffset];
    } else {
        var sx, sy, d = document,
            r = d.documentElement,
            b = d.body;
        sx = r.scrollLeft || b.scrollLeft || 0;
        sy = r.scrollTop || b.scrollTop || 0;
        return [sx, sy];
    }
}

mengembalikan array dengan dua bilangan bulat- [scrollLeft, scrollTop]

kennebec
sumber
4
Menampilkan cara menggunakan fungsi ini dengan contoh akan sangat bagus.
user18490
1
Saya kira Anda dapat menggunakan lastscroll = getScroll (); window.scrollTo (lastscroll [0], lastscroll [1]);
Dinesh Rajan
Bekerja dengan baik tetapi saya mengubah kembali ke objek dengan kunci x dan y karena itu membuat sedikit lebih masuk akal bagi saya.
xd6_
Diedit setelah komentar @ user18490.
Davide Cannizzo
ReferenceError: Tidak dapat menemukan variabel: elemen
Jonny
33

seperti ini :)

window.addEventListener("scroll", function (event) {
    var scroll = this.scrollY;
    console.log(scroll)
});
Pastor Brayan
sumber
11

Jawaban untuk 2018 :

Cara terbaik untuk melakukan hal-hal seperti itu adalah dengan menggunakan Intersection Observer API .

Intersection Observer API menyediakan cara untuk secara asinkron mengamati perubahan di persimpangan elemen target dengan elemen leluhur atau dengan viewport dokumen tingkat atas.

Secara historis, mendeteksi visibilitas suatu elemen, atau visibilitas relatif dari dua elemen dalam hubungannya satu sama lain, merupakan tugas yang sulit karena solusinya tidak dapat diandalkan dan cenderung menyebabkan peramban dan situs yang diakses pengguna menjadi lamban. Sayangnya, ketika web telah matang, kebutuhan akan informasi semacam ini telah berkembang. Informasi titik-temu diperlukan karena berbagai alasan, seperti:

  • Pemuatan gambar atau konten lain dengan malas seperti halaman digulir.
  • Menerapkan situs web "pengguliran tak terbatas", di mana semakin banyak konten dimuat dan ditampilkan saat Anda menggulir, sehingga pengguna tidak perlu membolak-balik halaman.
  • Pelaporan visibilitas iklan untuk menghitung pendapatan iklan.
  • Memutuskan apakah akan melakukan tugas atau proses animasi berdasarkan pada apakah pengguna akan melihat hasilnya atau tidak.

Menerapkan deteksi persimpangan di masa lalu melibatkan event handler dan loop memanggil metode seperti Element.getBoundingClientRect () untuk membangun informasi yang diperlukan untuk setiap elemen yang terpengaruh. Karena semua kode ini berjalan di utas utama, bahkan salah satunya dapat menyebabkan masalah kinerja. Ketika sebuah situs dimuat dengan tes-tes ini, semuanya bisa menjadi sangat buruk.

Lihat contoh kode berikut:

var options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

var observer = new IntersectionObserver(callback, options);

var target = document.querySelector('#listItem');
observer.observe(target);

Sebagian besar browser modern mendukung IntersectionObserver , tetapi Anda harus menggunakan polyfill untuk kompatibilitas ke belakang.

str
sumber
8

jika Anda peduli untuk seluruh halaman. Anda bisa menggunakan ini:

document.body.getBoundingClientRect().top

lemospy
sumber
1
gunakan document.body sebagai gantinya
danial dezfouli
3

Jika Anda menggunakan jQuery, ada fungsi yang sempurna untuk Anda: .scrollTop ()

doc di sini -> http://api.jquery.com/scrollTop/

catatan: Anda dapat menggunakan fungsi ini untuk mengambil ATAU mengatur posisi.

lihat juga: http://api.jquery.com/?s=scroll

Simon si Salmon
sumber
25
Mengapa menjawab pertanyaan tentang JS dengan pustaka untuk JS, ketika benar-benar mungkin dan bahkan nyaman untuk melakukannya dalam JS mentah? Anda hanya memintanya untuk menambahkan waktu buka tambahan serta menggunakan beberapa penyimpanan untuk sesuatu yang sama sekali tidak perlu. Juga, sejak kapan javascript mulai berarti JQuery?
DaemonOfTheWest
4
jika Anda bertanya secara individual, saya tidak pernah menyukai jQuery dan saya belum menjawab pertanyaan ini, tetapi di Vanilla JS sudah ada jawaban yang diberikan oleh orang lain, lalu apa masalahnya jika ada orang yang menambahkan bumbu lezat di utas ini. (Dia sudah menyebutkan bahwa jika Anda menggunakan jQuery)
Ravinder Payal
@ R01010010 itu karena sekarang ini JQuery tidak berguna dan kontraproduktif, semua fitur dari JQuery mudah diimplementasikan dengan VanilaJS, juga Anda menjadi tergantung pada apa yang ada di dalam JQuery, dengan fitur-fitur baru yang tersedia di VanillsaJS, Anda sebagai programmer, tidak akan memperbarui, seperti contoh , sekarang ada API baru di VanillaJS yang disebut fetch yang menggantikan XHR lama, jika Anda baru saja berada di dunia JQuery tidak akan pernah melihat manfaat dari mengambil dan terus menggunakan jQuery.ajax (). Pendapat pribadi saya adalah bahwa orang yang melanjutkan menggunakan JQuery itu karena mereka berhenti belajar. Juga VanillaJS lebih cepat vanilla-js.com
John Balvin Arias
@ JohnBalvinArias berbicara tentang mengambil, ada apa di ie11 atau bahkan Edge?
Ben
Koreksi saya jika saya salah, tetapi mengambil tidak berfungsi dengan benar yaitu "modern" yaitu, dan yaitu masih digunakan secara luas. Jika saya menggunakan jquery, saya tidak akan terdorong untuk melanjutkan
Ben
3

Berikut cara lain untuk mendapatkan posisi gulir

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
Gor
sumber
0

Saya pikir fungsi berikut dapat membantu memiliki nilai koordinat gulir:

const getScrollCoordinate = (el = window) => ({
  x: el.pageXOffset || el.scrollLeft,
  y: el.pageYOffset || el.scrollTop,
});

Saya mendapat ide ini dari jawaban ini dengan sedikit perubahan.

Amerika
sumber