Hoãn công việc cho đến khi cuộn xong

Tính năng web: scrollend

Thao tác cuộn trên web phải mượt mà và thích ứng. Việc thực thi các tác vụ nặng (chẳng hạn như tính toán lại bố cục, theo dõi đèn hiệu dữ liệu phân tích hoặc cập nhật DOM động) trong khi cuộn có thể làm bão hoà luồng chính, dẫn đến tình trạng rớt khung hình và bố cục bị giật.

Trước đây, các nhà phát triển đã dựa vào việc gỡ lỗi sự kiện scroll bằng cách sử dụng setTimeout() để đoán thời điểm cuộn xong. Tuy nhiên, các hàm chống dội này nổi tiếng là không đáng tin cậy. Quảng cáo có thể kích hoạt trong khi người dùng vẫn đang cuộn.

Sự kiện scrollend là một giải pháp đáng tin cậy và dựa trên hiệu suất. Trình duyệt kích hoạt sự kiện scrollend chính xác khi thao tác cuộn đã dừng, tất cả hiệu ứng chuyển đổi đã hoàn tất và cử chỉ chạm đã được nhả.

Cách triển khai

Cách triển khai mẫu trì hoãn công việc:

  1. Thiết lập vùng chứa có thể cuộn: Tạo vùng chứa bằng overflow: auto hoặc overflow: scroll.
  2. Theo dõi các sự kiện scroll: Chỉ sử dụng trình nghe này cho các chỉ số động cơ bản hoặc kiểu bố cục cung cấp thông tin. Đừng thực hiện công việc nặng ở đây.
  3. Theo dõi các sự kiện scrollend: Đăng ký lệnh gọi lại scrollend trên vùng chứa cuộn hoặc chính tài liệu đó.
  4. Thực thi công việc tốn kém trong lệnh gọi lại: Đây là nơi an toàn để tìm nạp nội dung động hoặc kích hoạt bố cục DOM toàn diện.

Mã ví dụ

.scroll-container {
  height: 300px;
  overflow-y: auto;
}
const scroller = document.querySelector('.scroll-container');

// 1. Informative feedback during scroll
scroller.addEventListener('scroll', () => {
  // Avoid dynamic heavier data updates here
  console.log('Scrolling dynamically... updates deferred');
});

// 2. Safe callback when scrolling rests
scroller.addEventListener('scrollend', () => {
  // Run layout recalculations or analytical beacons updates here
  const currentVisibleSection = findMostVisibleSection(scroller);
  fetchAdditionalData(currentVisibleSection);
});

Triển khai chiến lược và các phương pháp hay nhất

  • NÊN sử dụng scrollend thay vì các sự kiện scroll đã loại bỏ hiện tượng dội lại khi kích hoạt đèn hiệu dữ liệu bố cục hoặc tìm nạp bố cục nội dung mới một cách linh động.
  • NÊN cân nhắc kết hợp thuộc tính này với các thao tác chụp nhanh scrollSnapChange hoặc scrollSnapChanging nếu bạn đang tạo băng chuyền hoặc trang trình bày thư viện lời chứng thực.
  • KHÔNG gói các bản cập nhật động phụ thuộc vào bố cục bên trong lệnh gọi lại cuộn hình ảnh động.
  • NÊN cân nhắc việc thu phóng và cuộn khung nhìn trực quan sẽ kích hoạt sự kiện scrollend một cách chính xác.

Chiến lược dự phòng

Đối với các trình duyệt không được hỗ trợ, hãy quay lại sự kiện scroll đã được gỡ bỏ bằng setTimeout để gửi sự kiện scrollend tuỳ chỉnh.

function initializeDemo() {
  const scroller = document.querySelector('#scroller');
  scroller.addEventListener('scrollend', () => {
    // Safe execution
  });
}

if ('onscrollend' in window) {
  initializeDemo();
} else {
  initializeDemo();
  const scroller = document.querySelector('#scroller');
  scroller.addEventListener('scroll', () => {
    clearTimeout(window.scrollendtimer);
    window.scrollendtimer = setTimeout(() => {
      scroller.dispatchEvent(new CustomEvent('scrollend'));
    }, 100);
  });
}