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 Technology Preview: supported.

Source

ลองใช้งาน

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

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

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

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

การใช้เหตุการณ์

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

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

aScrollingElement.addEventListener("scrollend", (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 เพื่อทริกเกอร์การทำงานต่างๆ ได้ กรณีการใช้งานทั่วไป คือการซิงค์องค์ประกอบ UI ที่เชื่อมโยงกับตำแหน่งที่การเลื่อน หยุด เช่น - การซิงค์ตำแหน่งการเลื่อนภาพสไลด์กับตัวบ่งชี้แบบจุด - การซิงค์รายการแกลเลอรีกับข้อมูลเมตา - การดึงข้อมูลหลังจากที่ผู้ใช้เลื่อนไปยังแท็บใหม่

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

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

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

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