Scrollend, một sự kiện JavaScript mới

Xoá các hàm thời gian chờ và loại bỏ lỗi của chúng, đây là sự kiện mà bạn thực sự cần: scrollend.

Trước sự kiện scrollend, không có cách nào đáng tin cậy để phát hiện rằng một 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 đang ở trên màn hình. Việc không biết chính xác thời điểm thao tác cuộn thực sự kết thúc dẫn đến lỗi và trải nghiệm không tốt cho người dùng.

Trước
document.onscroll = event => {
  clearTimeout(window.scrollEndTimer)
  window.scrollEndTimer = setTimeout(callback, 100)
}

Chiến lược setTimeout() này có thể 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ả quy trình đánh giá khó khăn này cho bạn.

Sau
document.onscrollend = event => {}

Đó là những điều tốt đẹp. Được tí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.

Browser Support

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 109.
  • Safari Technology Preview: supported.

Source

Hãy làm thử!

Chi tiết sự kiện

Sự kiện scrollend sẽ kích hoạt khi: - Trình duyệt không còn tạo hiệu ứng động hoặc dịch chuyển thao tác cuộn. – Người dùng đã nhấc ngón tay lên. – Con trỏ của người dùng đã thả ngón tay cái cuộn. – Người dùng đã nhả phím. – Đã hoàn tất thao tác chuyển đến đoạn văn bản. – Đã hoàn tất thao tác cuộn nhanh. – scrollTo() đã hoàn tất. – Người dùng đã cuộn khung hiển thị 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 tạo ra 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 được chỉ định. 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 về scrollend cho Khung hiển thị ảo 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ể di chuyển xung quanh khi ở trạng thái phóng to này và không nhất thiết phải di chuyển tài liệu. Hãy yên tâm rằng ngay cả tương tác cuộn do người dùng thực hiện trong khung hiển thị 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("scrollend", (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ờ, thì đây là lời khuyên tốt 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à kiểm tra khả năng hỗ trợ ở đầu chiến lược đó bằng cách:

'onscrollend' in window
// true, if available

Điều này sẽ báo cáo là 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 bước 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)
  }
}

Đó là một khởi đầu tốt để tăng cường dần sự kiện scrollend khi có sẵn. Bạn cũng có thể thử một polyfill (NPM) mà tôi đã tạo để thực hiện những gì tốt nhất mà trình duyệt có thể làm:

import {scrollend} from "scrollyfills"

// then use scrollend as if it's existed this whole time
document.onscrollend = callback

Polyfill sẽ tăng cường dần để sử dụng sự kiện scrollend tích hợp sẵn của 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 tốt nhất có thể về sự kiện kết thúc.

Trường hợp sử dụng

Bạn nên tránh thực hiện các thao tác tốn nhiều tài nguyên tính toán trong khi đang cuộn. Phương pháp này đảm bảo hoạt động cuộn có thể sử dụng nhiều bộ nhớ và khả năng xử lý nhất có thể để mang lại trải nghiệm mượt mà. Việc sử dụng sự kiện scrollend là thời điểm thích hợp để gọi ra 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ử liên kết trên giao diện người dùng với vị trí mà thao tác cuộn đã dừng. 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 cuộ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 để loại bỏ email. Sau khi người dùng vuốt xong, bạn có thể thực hiện hành động dựa trên vị trí mà họ đã vuốt.

Bạn cũng có thể dùng sự kiện này để đồng bộ hoá sau khi cuộn theo chương trình hoặc theo người dùng, hoặc các thao tác như ghi nhật ký phân tích.

Sau đây là một ví dụ điển hình 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ì công việc kỹ thuật của anh ấy về vấn đề này và Robert Flack vì hướng dẫn về API và việc triển khai.