Scrollend เหตุการณ์ JavaScript ใหม่

ลบฟังก์ชันการหมดเวลาและกำจัดข้อบกพร่องออกไป เหตุการณ์ที่คุณต้องการจริงๆ คือ scrollend

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

ก่อน
document.onscroll = event => {
  clearTimeout(window.scrollEndTimer)
  window.scrollEndTimer = setTimeout(callback, 100)
}

สิ่งที่ดีที่สุดที่กลยุทธ์ setTimeout() นี้ทำได้คือการทราบว่าการเลื่อนหยุดลงเป็นเวลา 100ms หรือไม่ ซึ่งทำให้เหตุการณ์นี้คล้ายกับเหตุการณ์การเลื่อนหยุดชั่วคราว ไม่ใช่เหตุการณ์การเลื่อนสิ้นสุดลง

หลังจากเหตุการณ์ scrollend เบราว์เซอร์จะทำการประเมินที่ซับซ้อนทั้งหมดนี้ให้คุณ

หลัง
document.onscrollend = event => {…}

นั่นแหละคือสิ่งดีๆ ซึ่งมีจังหวะเวลาที่สมบูรณ์แบบและเต็มไปด้วยเงื่อนไขที่มีความหมายก่อนที่จะปล่อยออกมา

Browser Support

  • Chrome: 114.
  • Edge: 114.
  • Firefox: 109.
  • Safari: 26.2.

Source

ลองใช้งาน

รายละเอียดเหตุการณ์

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

เหตุการณ์ scrollend จะไม่เริ่มทำงานในกรณีต่อไปนี้ - ท่าทางสัมผัสของผู้ใช้ไม่ได้ส่งผลให้เกิดการเปลี่ยนแปลงตำแหน่งการเลื่อน (ไม่มีการแปลเกิดขึ้น) - scrollTo() ไม่ได้ส่งผลให้เกิดการแปลใดๆ

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

การใช้กิจกรรม

คุณสามารถลงทะเบียน Listener ได้หลายวิธีเช่นเดียวกับเหตุการณ์การเลื่อนอื่นๆ

addEventListener("scrollend",> (event) = {
  // scroll ended
});

aScrollingElement.addEventListener("scroll>end", (event) = {
  // scroll ended
});

หรือใช้พร็อพเพอร์ตี้เหตุการณ์ต่อไปนี้

document.onscrollend = (event) => {
  // scroll ended
};

aScrollingElement.onscrollend = (event) => {
  // scroll ended
};

Polyfill และการเพิ่มประสิทธิภาพแบบต่อเนื่อง

หากคุณต้องการใช้เหตุการณ์ใหม่นี้ในตอนนี้ เราขอแนะนำให้ทำดังนี้ คุณสามารถใช้กลยุทธ์การสิ้นสุดการเลื่อนปัจจุบันต่อไปได้ (หากมี) และตรวจสอบการรองรับที่จุดเริ่มต้นของกลยุทธ์ด้วยวิธีต่อไปนี้

'onscrollend' in window
// true, if available

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

if ('onscrollend' in window) {
  document.onscrollend = callback
}
else {
  document.onscroll => event = {
    clearTimeout(window.scrollEndTimer)
    window.scrollEndTimer = setTimeout(callback, 100)
  }
}

ซึ่งถือเป็นการเริ่มต้นที่ดีในการปรับปรุงเหตุการณ์ scrollend อย่างต่อเนื่องเมื่อพร้อมใช้งาน คุณยังลองใช้ polyfill (NPM) ที่ฉันสร้างขึ้นซึ่งทำงานได้ดีที่สุดเท่าที่เบราว์เซอร์จะทำได้ ดังนี้

import {scrollend} from "scrollyfills"

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

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

กรณีการใช้งาน

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

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

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

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

ต่อไปนี้เป็นตัวอย่างที่ดีซึ่งต้องอัปเดตองค์ประกอบหลายอย่าง เช่น ลูกศร จุด และโฟกัส ตามตำแหน่งการเลื่อน ดูวิธีที่ฉันสร้างภาพสไลด์นี้บน YouTube นอกจากนี้ ให้ลองใช้เดโมแบบสด

ขอขอบคุณ Mehdi Kazemi สำหรับงานด้านวิศวกรรมในเรื่องนี้ และ Robert Flack สำหรับคำแนะนำเกี่ยวกับ API และการติดตั้งใช้งาน