เลื่อนการทำงานออกไปจนกว่าจะเลื่อนหน้าจอเสร็จ

ฟีเจอร์บนเว็บ: scrollend

การเลื่อนบนเว็บควรราบรื่นและตอบสนองได้ดี การทำงานที่หนักหน่วง เช่น การคำนวณเลย์เอาต์ใหม่ การติดตามบีคอนข้อมูลการวิเคราะห์ หรือการอัปเดต DOM แบบไดนามิก ระหว่างการเลื่อนอาจทำให้เทรดหลักทำงานหนักเกินไป ส่งผลให้เฟรมหายไปและเลย์เอาต์ทำงานผิดพลาด

ที่ผ่านมา นักพัฒนาอาศัยการดีเบานซ์เหตุการณ์ scroll โดยใช้ setTimeout() เพื่อคาดเดาว่าการเลื่อนเสร็จสิ้นเมื่อใด อย่างไรก็ตาม ฟังก์ชันที่ลดการตีกลับเหล่านี้ขึ้นชื่อว่าไม่น่าเชื่อถือ โดยอาจทริกเกอร์ขณะที่ผู้ใช้ยังเลื่อนดูอยู่

กิจกรรม scrollend เป็นโซลูชันที่เชื่อถือได้สูงและขับเคลื่อนด้วยประสิทธิภาพ เบราว์เซอร์จะเริ่มเหตุการณ์ scrollend เมื่อการเลื่อนหยุดลง การเปลี่ยนทั้งหมดเสร็จสิ้น และมีการปล่อยท่าทางสัมผัส

วิธีการนำไปใช้งาน

วิธีใช้รูปแบบการเลื่อนงานออกไป

  1. ตั้งค่าคอนเทนเนอร์ที่เลื่อนได้: สร้างคอนเทนเนอร์ที่มี overflow: auto หรือ overflow: scroll
  2. รอรับเหตุการณ์ scroll: ใช้ Listener นี้สำหรับเมตริกแบบไดนามิกพื้นฐานหรือการจัดรูปแบบเลย์เอาต์ที่ให้ข้อมูลเท่านั้น อย่าทำงานหนักที่นี่
  3. คอยฟังเหตุการณ์ scrollend: ลงทะเบียน Callback scrollend ในคอนเทนเนอร์การเลื่อนหรือตัวเอกสารเอง
  4. ดำเนินการงานที่ใช้ทรัพยากรมากใน Callback: ขั้นตอนนี้เป็นขั้นตอนที่ปลอดภัยในการดึงข้อมูลเนื้อหาแบบไดนามิกหรือทริกเกอร์เลย์เอาต์ DOM ที่ครอบคลุม

โค้ดตัวอย่าง

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

การนำไปใช้เชิงกลยุทธ์และแนวทางปฏิบัติแนะนำ

  • ควรใช้ scrollend แทนเหตุการณ์ scroll ที่มีการหน่วงเวลาเมื่อเริ่มทำงานบีคอนข้อมูลเลย์เอาต์หรือดึงข้อมูลเลย์เอาต์เนื้อหาใหม่แบบไดนามิก
  • ควรพิจารณาใช้ร่วมกับการโต้ตอบแบบสแนป scrollSnapChange หรือ scrollSnapChanging หากคุณกำลังสร้างภาพสไลด์หรือสไลด์แกลเลอรีคำรับรอง
  • อย่ารวมการอัปเดตแบบไดนามิกที่ขึ้นอยู่กับเลย์เอาต์ไว้ใน Callback ของการเลื่อนภาพแบบไดนามิก
  • ควรพิจารณาว่าการซูมและการเลื่อนวิวพอร์ตภาพทริกเกอร์เหตุการณ์ scrollend อย่างถูกต้อง

กลยุทธ์สำรอง

สำหรับเบราว์เซอร์ที่ไม่รองรับ ให้กลับไปใช้เหตุการณ์ scroll ที่มีการหน่วงเวลาด้วย setTimeout เพื่อส่งเหตุการณ์ scrollend ที่กำหนดเอง

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