Xoá các hàm thời gian chờ và loại bỏ lỗi, đây là sự kiện bạn thực sự cần: scrollend.
Trước khi có sự kiện scrollend, không có cách nào đáng tin cậy để phát hiện thao tác cuộn đã hoàn tất. Điều này có nghĩa là các sự kiện sẽ kích hoạt muộn hoặc trong khi ngón tay của người dùng vẫn còn trên màn hình. Sự không chắc chắn về thời điểm thao tác cuộn thực sự kết thúc này đã dẫn đến lỗi và trải nghiệm không tốt cho người dùng.
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
Điều tốt nhất mà chiến lược setTimeout() này có thể làm là biết liệu thao tác cuộn đã dừng cho 100ms hay chưa. Điều này khiến sự kiện này giống với sự kiện cuộn đã tạm dừng hơn là sự kiện cuộn đã kết thúc.
Sau sự kiện scrollend, trình duyệt sẽ thực hiện tất cả các bước đánh giá khó khăn này cho bạn.
document.onscrollend = event => {…}
Đó là những điều tốt đẹp. Được định thời gian hoàn hảo và chứa đầy đủ các điều kiện có ý nghĩa trước khi phát ra.
Hãy làm thử!
Chi tiết sự kiện
Sự kiện scrollend kích hoạt khi:
– Trình duyệt không còn tạo ảnh động hoặc chuyển đổi thao tác cuộn.
– Người dùng đã thả tay ra.
– Con trỏ của người dùng đã thả thanh cuộn.
– Người dùng đã nhả phím.
– Đã hoàn tất thao tác cuộn đến mảnh.
– Đã hoàn tất việc cố định vị trí cuộn.
– scrollTo() đã hoàn tất.
– Người dùng đã cuộn khung nhìn trực quan.
Sự kiện scrollend không kích hoạt khi:
– Cử chỉ của người dùng không dẫn đến bất kỳ thay đổi nào về vị trí cuộn (không có bản dịch nào xảy ra).
– scrollTo() không có bản dịch nào.
Một lý do khiến sự kiện này mất nhiều thời gian để xuất hiện trên nền tảng web là do có nhiều chi tiết nhỏ cần thông tin chi tiết về thông số kỹ thuật. Một trong những khía cạnh phức tạp nhất
là việc trình bày chi tiết scrollend cho Khung nhìn trực quan
so với tài liệu. Hãy xem xét một trang web mà bạn phóng to. Bạn có thể cuộn xung quanh khi ở trạng thái thu phóng này và không nhất thiết phải cuộn tài liệu. Bạn có thể yên tâm rằng ngay cả hoạt động tương tác cuộn do người dùng điều khiển trong khung nhìn trực quan này cũng sẽ phát ra sự kiện scrollend sau khi hoàn tất.
Sử dụng sự kiện
Giống như các sự kiện cuộn khác, bạn có thể đăng ký trình nghe theo một số cách.
addEventListener("scrollend",> (event) = {
// scroll ended
});
aScrollingElement.addEventListener("scroll>end", (event) = {
// scroll ended
});
hoặc sử dụng thuộc tính sự kiện:
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
Polyfill và cải tiến tăng dần
Nếu bạn muốn sử dụng sự kiện mới này ngay bây giờ, hãy tham khảo lời khuyên hữu ích nhất của chúng tôi. Bạn có thể tiếp tục sử dụng chiến lược kết thúc cuộn hiện tại (nếu có) và ở đầu chiến lược đó, hãy kiểm tra khả năng hỗ trợ bằng:
'onscrollend' in window
// true, if available
Hàm này sẽ trả về giá trị true hoặc false tuỳ thuộc vào việc trình duyệt có cung cấp sự kiện hay không. Với kiểm tra này, bạn có thể phân nhánh mã:
if ('onscrollend' in window) {
document.onscrollend = callback
}
else {
document.onscroll => event = {
clearTimeout(window.scrollEndTimer)
window.scrollEndTimer = setTimeout(callback, 100)
}
}
Đây là một khởi đầu tốt để cải tiến tăng dần sự kiện scrollend khi sự kiện này có sẵn. Bạn cũng có thể thử một
polyfill
(NPM) mà tôi đã tạo để trình duyệt có thể làm tốt nhất:
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
Polyfill sẽ dần cải tiến tăng dần để sử dụng sự kiện scrollend tích hợp sẵn trong trình duyệt (nếu có). Nếu không có, tập lệnh sẽ theo dõi các sự kiện con trỏ và
cuộn để ước tính chính xác nhất có thể về thời điểm kết thúc sự kiện.
Trường hợp sử dụng
Bạn nên tránh thực hiện các thao tác tính toán nặng trong khi cuộn. Phương pháp này đảm bảo thao tác cuộn có thể sử dụng nhiều bộ nhớ và xử lý nhiều nhất có thể để duy trì trải nghiệm mượt mà. Việc sử dụng sự kiện scrollend là thời điểm hoàn hảo để gọi và thực hiện công việc khó khăn, vì thao tác cuộn không còn diễn ra nữa.
Bạn có thể dùng sự kiện scrollend để kích hoạt nhiều hành động. Một trường hợp sử dụng phổ biến là đồng bộ hoá các phần tử trên giao diện người dùng liên quan với vị trí mà thao tác cuộn dừng lại. Ví dụ:
– Đồng bộ hoá vị trí cuộn của băng chuyền với chỉ báo dấu chấm.
– Đồng bộ hoá một mục trong thư viện với siêu dữ liệu của mục đó.
– Tìm nạp dữ liệu sau khi người dùng di chuyển đến một thẻ mới.
Hãy tưởng tượng một trường hợp như người dùng vuốt để xoá email. Sau khi họ vuốt xong, bạn có thể thực hiện hành động dựa trên vị trí họ đã cuộn đến.
Bạn cũng có thể sử dụng sự kiện này để đồng bộ hoá sau khi người dùng hoặc chương trình cuộn, hoặc các hành động như ghi nhật ký phân tích.
Dưới đây là một ví dụ hay về trường hợp cần cập nhật nhiều phần tử (chẳng hạn như mũi tên, dấu chấm và tiêu điểm) dựa trên vị trí cuộn. Xem cách tôi tạo băng chuyền này trên YouTube. Ngoài ra, hãy thử bản minh hoạ trực tiếp.
Cảm ơn Mehdi Kazemi vì đã thực hiện công việc kỹ thuật này và Robert Flack vì đã hướng dẫn về API và cách triển khai.