Làm thế nào để có được vị trí thanh cuộn với Javascript?


188

Tôi đang cố gắng phát hiện vị trí của thanh cuộn của trình duyệt bằng JavaScript để quyết định vị trí của trang hiện tại. Tôi đoán là tôi phải phát hiện ngón tay cái trên đường đua ở đâu, và sau đó chiều cao của ngón tay cái là phần trăm của tổng chiều cao của đường đua. Tôi có quá phức tạp với nó không, hay JavaScript có cung cấp một giải pháp dễ dàng hơn thế không? Bất kỳ ý tưởng mã khôn ngoan?

Câu trả lời:


207

Bạn có thể sử dụng element.scrollTopelement.scrollLeftđể có được phần bù dọc và ngang tương ứng, đã được cuộn. elementcó thể là document.bodynếu bạn quan tâm đến toàn bộ trang. Bạn có thể so sánh nó với element.offsetHeightelement.offsetWidth(một lần nữa, elementcó thể là cơ thể) nếu bạn cần tỷ lệ phần trăm.


2
Bạn đang dùng trình duyệt nào? Việc lấy phần thân được thực hiện khác nhau trong các trình duyệt khác nhau ( elementdocument.bodychỉ là ví dụ). Xem howtocreate.co.uk/tutorials/javascript/browserwindow để biết chi tiết.
Tối đa Shawabkeh

8
Tôi đã nhận được nó để cung cấp cho tôi giá trị chính xác trên Firefox 3.6 window.pageYOffset, nhưng không thể có bất cứ điều gì hoạt động trên IE7. Cố gắng window.pageYOffset, document.body.scrollTop, document.documentElement.scrollTop,element.scrollTop
Paul

1
scrollTop chỉ hoạt động với tôi khi tôi thêm dấu ngoặc ... $ (". scrollBody"). scrollTop ()
maia

9
Nếu bạn đang xử lý phần tử 'window', bạn có thể sử dụng window.scrollY thay vì window.scrollTop
Janis Jansen

6
Tôi nghĩ rằng vị trí cuộn không được đặt document.bodytrong hầu hết các trình duyệt hiện đại - nó thường được đặt document.documentElementngay bây giờ. Xem bug.chromium.org/p/chromium/issues/detail?id=157855 để biết quá trình chuyển đổi của Chrome.
fzzfzzfzz

134

Tôi đã làm điều này cho một <div>trên Chrome.

phần tử .scrollTop - là các pixel bị ẩn ở trên cùng do cuộn. Không có cuộn giá trị của nó là 0.

phần tử .scrollHeight - là pixel của toàn bộ div.

phần tử .clientHeight - là các pixel mà bạn nhìn thấy trong trình duyệt của mình.

var a = element.scrollTop;

sẽ là vị trí.

var b = element.scrollHeight - element.clientHeight;

sẽ là giá trị tối đa cho scrollTop .

var c = a / b;

sẽ là phần trăm cuộn [từ 0 đến 1] .


Cảm ơn! Có lẽ không phải từ 0 đến 1, vì bạn thực sự không thể cuộn xuống dưới cùng của phần tử, phải không?

3
Điều này gần như đúng. đối với var b, bạn nên trừ window.innerHeight không 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];
    }
}

trả về một mảng có hai số nguyên- [scrollLeft, scrollTop]


4
Chỉ ra cách sử dụng chức năng này với một ví dụ sẽ rất tuyệt.
dùng18490

1
Tôi đoán bạn có thể sử dụng lastscroll = getScroll (); window.scrollTo (lastscroll [0], lastscroll [1]);
Dinesh Rajan

Hoạt động rất tốt nhưng tôi đã thay đổi trở lại thành một đối tượng với các phím x và y vì điều đó có ý nghĩa hơn đối với tôi.
xd6_ 24/07/2015

Đã chỉnh sửa sau bình luận của @ user18490.
Davide Cannizzo

ReferenceError: Không thể tìm thấy biến: phần tử
Jonny

32

nó như thế này :)

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

11

Trả lời năm 2018 :

Cách tốt nhất để làm những việc như vậy là sử dụng API Intersection Observer .

API quan sát giao nhau cung cấp một cách để quan sát không đồng bộ các thay đổi trong giao điểm của phần tử đích với phần tử tổ tiên hoặc với chế độ xem của tài liệu cấp cao nhất.

Trong lịch sử, việc phát hiện khả năng hiển thị của một yếu tố hoặc khả năng hiển thị tương đối của hai yếu tố liên quan đến nhau là một nhiệm vụ khó khăn khi các giải pháp không đáng tin cậy và dễ khiến trình duyệt và các trang web mà người dùng đang truy cập trở nên chậm chạp. Thật không may, khi web đã trưởng thành, nhu cầu về loại thông tin này đã tăng lên. Thông tin giao nhau là cần thiết vì nhiều lý do, chẳng hạn như:

  • Lười tải hình ảnh hoặc nội dung khác khi một trang được cuộn.
  • Triển khai các trang web "cuộn vô hạn", trong đó ngày càng có nhiều nội dung được tải và hiển thị khi bạn cuộn, để người dùng không phải lướt qua các trang.
  • Báo cáo về khả năng hiển thị của quảng cáo để tính toán doanh thu quảng cáo.
  • Quyết định có thực hiện các tác vụ hoặc quy trình hoạt hình hay không dựa trên việc người dùng có nhìn thấy kết quả hay không.

Việc thực hiện phát hiện giao lộ trong quá khứ liên quan đến các trình xử lý sự kiện và các vòng lặp gọi các phương thức như Element.getBoundingClientRect () để xây dựng thông tin cần thiết cho mọi thành phần bị ảnh hưởng. Vì tất cả các mã này chạy trên luồng chính, thậm chí một trong số này có thể gây ra vấn đề về hiệu năng. Khi một trang web được tải với các thử nghiệm này, mọi thứ có thể trở nên hết sức xấu xí.

Xem ví dụ mã sau:

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);

Hầu hết các trình duyệt hiện đại đều hỗ trợ IntersectionObserver , nhưng bạn nên sử dụng polyfill để tương thích ngược.



3

Nếu bạn đang sử dụng jQuery, có một hàm hoàn hảo cho bạn: .scrollTop ()

tài liệu ở đây -> http://api.jquery.com/scrollTop/

lưu ý: bạn có thể sử dụng chức năng này để truy xuất HOẶC đặt vị trí.

xem thêm: http://api.jquery.com/?s=scroll


25
Tại sao trả lời một câu hỏi về JS với một thư viện cho JS, khi nó hoàn toàn có thể và thậm chí thuận tiện để làm điều đó trong JS thô? Bạn chỉ yêu cầu anh ta thêm thời gian tải bổ sung cũng như sử dụng hết dung lượng lưu trữ cho những thứ hoàn toàn không cần thiết. Ngoài ra, từ khi nào javascript bắt đầu có nghĩa là JQuery?
DaemonOfTheWest

4
Nếu bạn hỏi riêng tôi không bao giờ thích jQuery và tôi chưa trả lời câu hỏi này nhưng trong Vanilla JS đã có câu trả lời được đưa ra bởi các đồng nghiệp khác thì có vấn đề gì nếu ai đó đã thêm một gia vị ngon trong chủ đề này. bạn đang sử dụng jQuery)
Ravinder Payal

@ R01010010 bởi vì ngày nay JQuery là vô dụng và phản tác dụng, tất cả các tính năng từ JQuery đều được triển khai dễ dàng với VanilaJS, bạn cũng trở nên phụ thuộc vào những gì bên trong JQuery, với các tính năng mới có trong VanillsaJS, bạn là người lập trình, sẽ không cập nhật, ví dụ như , ngày nay, có một API mới trong VanillaJS được gọi là fetch thay thế XHR cũ, nếu bạn ở trong thế giới của JQuery sẽ không bao giờ thấy lợi ích khi tìm nạp và tiếp tục sử dụng jQuery.ajax (). Ý kiến ​​cá nhân của tôi là những người tiếp tục sử dụng JQuery vì họ đã ngừng học. Ngoài ra VanillaJS là vanilla-js.com nhanh hơn
John Balvin Arias

@JohnBalvinArias nói về tìm nạp, có gì trên eg11 hoặc thậm chí Edge?
Ben

Sửa lỗi cho tôi nếu tôi sai, nhưng tìm nạp không hoạt động đúng với nghĩa là "hiện đại", và nghĩa là vẫn được sử dụng rộng rãi. Nếu tôi đang sử dụng jquery, tôi sẽ khó được khuyến khích tiếp tục sau đó
Ben

3

Đây là cách khác để có được vị trí cuộn

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

0

Tôi nghĩ rằng chức năng sau đây có thể giúp có các giá trị tọa độ cuộn:

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

Tôi có ý tưởng từ câu trả lời này với một chút thay đổi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.